IntegrityError:删除时出现外键冲突

时间:2010-03-30 07:25:48

标签: sql database django postgresql django-models

我有订单和发货模型。装运有订购的外键。

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)'}

外键具有ON DELETE NO ACTION(默认值)并且最初是延迟的。我不知道为什么我会遇到外键约束违规。

我还尝试注册pre_delete信号并在调用订单删除之前手动删除货件对象,但导致同样的错误。

我可以在Postgres中更改此键的ON DELETE行为,但这只是一个黑客,我想知道是否有人更好地了解这里发生了什么。

还有一个小细节,我的Order模型继承自Cart模型,所以它实际上没有id字段而是cart_ptr_id,并且在执行DELETE后执行时,购物车上也有DELETE,但它似乎无关?发货 - >订单问题所以我在示例中简化了它。

1 个答案:

答案 0 :(得分:4)

  

详细信息:键(id)=(45)仍然是   从表“main_shipment”引用。

仍然有一个记录引用id 45.您之前删除了main_shipment中的记录17,但也可能有其他记录。您必须删除main_shipment中引用main_order中id 45的所有记录。如果没有,数据库可以保护您免受数据损害。