2010-03-30 39 views
5

Tôi có mô hình Đơn hàng và Lô hàng. Lô hàng có khóa ngoại để đặt hàng.IntegrityError: vi phạm khóa ngoài khi xóa

class Order(...): 
    ... 

class Shipment() 
    order = m.ForeignKey('Order') 
    ... 

Bây giờ trong một quan điểm của tôi, tôi muốn xóa đối tượng đơn hàng cùng với tất cả các đối tượng liên quan. Vì vậy, tôi gọi order.delete().

Tôi có Django 1.0.4, PostgreSQL 8.4 và tôi sử dụng phần mềm trung gian giao dịch, vì vậy toàn bộ yêu cầu được đính kèm trong giao dịch đơn lẻ.

Vấn đề là khi order.delete() tôi nhận được:

... 
File "/usr/local/lib/python2.6/dist-packages/django/db/backends/__init__.py", line 28, in _commit 
return self.connection.commit() 

IntegrityError: update or delete on table "main_order" violates 
foreign key constraint "main_shipment_order_id_fkey" on table "main_shipment" 
DETAIL: Key (id)=(45) is still referenced from table "main_shipment". 

Tôi đã kiểm tra trong connection.queries rằng các truy vấn thích hợp được thực hiện theo đúng thứ tự. Lô hàng đầu tiên bị xóa, sau đó django thực hiện xóa trên hàng đơn đặt hàng:

{'time': '0.000', 'sql': 'DELETE FROM "main_shipment" WHERE "id" IN (17)'}, 
{'time': '0.000', 'sql': 'DELETE FROM "main_order" WHERE "id" IN (45)'} 

Khóa ngoại đã ON XÓA KHÔNG HÀNH ĐỘNG (mặc định) và ban đầu được hoãn lại. Tôi không biết tại sao tôi bị vi phạm ràng buộc khoá ngoại.

Tôi cũng đã cố gắng đăng ký tín hiệu trước khi xóa và xóa đối tượng lô hàng theo cách thủ công trước khi xóa theo thứ tự được gọi, nhưng kết quả là lỗi tương tự.

Tôi có thể thay đổi ON DELETE hành vi cho khóa này trong Postgres nhưng nó sẽ chỉ là một hack, tôi tự hỏi nếu có ai có một ý tưởng tốt hơn những gì đang xảy ra ở đây.

Ngoài ra còn có một chi tiết nhỏ, mô hình đặt hàng của tôi kế thừa từ mô hình giỏ hàng, vì vậy nó thực sự không có trường id nhưng cart_ptr_id và sau khi DELETE trên đơn hàng được thực hiện cũng có DELETE trên giỏ hàng, nhưng có vẻ như không liên quan? cho vấn đề lô hàng -> vì vậy tôi đã đơn giản hóa nó trong ví dụ.

+0

Vâng tôi đã thử điều này trong giao diện điều khiển psql, và kết quả tương tự, do đó, nó là đúng postgreql vấn đề. Maybye Tôi không nhận được công việc trì hoãn như thế nào. –

+0

Bạn có thể cung cấp SQL tạo bảng có liên quan không? – Unreason

+0

Tại sao bạn xóa các đơn đặt hàng có lô hàng? Nói chung đây là điều bạn muốn thất bại. Bạn không muốn xóa các lô hàng thực tế, bao giờ hết. – HLGEM

Trả lời

4

DETAIL: Key (id)=(45) is still referenced from table "main_shipment".

Vẫn còn bản ghi tham chiếu đến id 45. Bạn đã xóa bản ghi 17 trong main_shipment trước đây, nhưng cũng có thể có bản ghi khác. Bạn phải xóa tất cả các bản ghi trong main_shipment tham chiếu đến id 45 trong main_order. Nếu không, cơ sở dữ liệu bảo vệ bạn khỏi làm hại đến dữ liệu của bạn.

+0

Ahhhhhh:/Tôi đã chiến đấu với nó quá lâu và tôi chỉ nhận ra rằng sau này trong mã python, trong khối mã cao hơn, tôi có shipment.save():/Và tôi đã không nhận thấy nó trong đầu ra conn.queries vì ​​nó đã được in trước khi shipment.save() được gọi. –

Các vấn đề liên quan