2010-03-30 100 views
5

我有訂單和貨物模型。貨件有訂購的外鍵。IntegrityError:外鍵衝突時刪除

class Order(...): 
    ... 

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

現在我的意見之一,我想刪除順序對象以及所有相關的對象。所以我調用了order.delete()。

我有Django的1.0.4,PostgreSQL的8.4和我使用事務中間件,所以整個請求被包圍在單個事務。

的問題是,在order.delete()我得到:

... 
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". 

我connection.queries檢查,適當的查詢按照正確的順序執行。第一批貨被刪除,之後Django的執行刪除命令行:

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

外鍵有DELETE NO ACTION(默認)和最初推遲。我不知道爲什麼我會違反外鍵約束。

我也試圖註冊pre_delete信號,並手動刪除裝運物品放在訂單之前刪除被調用,但它導致了同樣的錯誤。

我可以在DELETE行爲更改Postgres裏這個關鍵,但它也不過一個黑客,我不知道如果任何人有一個更好的主意什麼是怎麼回事。

還有一個小細節,我的Order模型繼承了Cart模型,所以它實際上沒有id字段,但cart_ptr_id和DELETE之後執行的命令執行時也有DELETE在購物車上,但它似乎不相關?到裝運 - >訂單問題,所以我在示例中簡化了它。

+0

嗯,我想這在PSQL控制檯,同樣的結果,所以它是嚴格postgreql事。 Maybye我不明白延遲作品。 – 2010-03-30 09:17:36

+0

你能提供相關的創建表SQL嗎? – Unreason 2010-03-30 10:38:26

+0

你爲什麼要刪除有貨件的訂單?一般來說,這是你想要失敗的事情。你不想刪除實際的貨物。 – HLGEM 2010-03-30 17:09:13

回答

4

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

還有引用到ID 45.你沒有在main_shipment之前刪除記錄17的記錄,但有可能是其他人。您必須刪除main_order中引用至​​id 45的main_shipment中的所有記錄。如果沒有,數據庫可以保護您免於損害您的數據。

+0

AHHHHHH:/我與它戰鬥這麼久,我才意識到,後來在Python代碼,在更高的代碼塊,我有shipment.save():/我沒有注意到它conn.queries輸出,因爲它是在shipment.save()被調用之前打印。 – 2010-03-30 10:47:45