IntegrityError:删除后违反外键 [英] IntegrityError: foreign key violation upon delete

查看:72
本文介绍了IntegrityError:删除后违反外键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have Order and Shipment model. Shipment has a foreign key to Order.

class Order(...):
   ...

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

现在在我想要的其中一个视图中,我要删除订单对象以及所有相关对象。所以我调用order.delete()。

Now in one of my views I want do delete order object along with all related objects. So I invoke order.delete().

我有Django 1.0.4,PostgreSQL 8.4,并且使用事务中间件,因此整个请求都包含在单个事务中。

I have Django 1.0.4, PostgreSQL 8.4 and I use transaction middleware, so whole request is enclosed in single transaction.

问题在于,在order.delete()上我得到了:

The problem is that upon order.delete() I get:

...
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.queue中查询了正确的查询是以正确的顺序执行的。删除第一批货物,然后django在订单行上执行删除操作:

I checked in connection.queries that proper queries are executed in proper order. First shipment is deleted, after that django executes delete on order row:

{'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(默认值)为ON,并且最初被推迟。我不知道为什么会违反外键约束。

Foreign key have ON DELETE NO ACTION (default) and is initially deferred. I don't know why I get foreign key constraint violation.

我也尝试注册pre_delete信号并在调用删除之前手动删除装运对象,但是结果

I also tried to register pre_delete signal and manually delete shipment objects before delete on order is called, but it resulted in the same error.

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

I can change ON DELETE behaviour for this key in Postgres but it would be just a hack, I wonder if anyone has a better idea what's going on here.

还有一个小细节,我的Order模型是从Cart模型继承的,所以它实际上没有id字段,但是cart_ptr_id,并且在执行了DELETE命令后购物车上也有DELETE,但似乎无关吗?到装运->订单问题,因此在示例中将其简化。

There is also a small detail, my Order model inherits from Cart model, so it actually doesn't have id field but cart_ptr_id and after DELETE on order is executed there is also DELETE on cart, but it seems unrelated? to the shipment->order problem so I simplified it in the example.

推荐答案


详细信息:密钥(id)=(45)仍然是从表 main_shipment引用的

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

仍然有一条记录指向id45。您之前确实删除过main_shipment中的记录17,但是可能还有其他记录。您必须删除main_shipment中的所有记录,并参考main_order中的id 45。如果不是这样,数据库将保护您免受对数据的损害。

There is still a record referencing to id 45. You did delete record 17 in main_shipment before, but there might be others as well. You have to delete all records in main_shipment referencing to id 45 in main_order. If not, the database protects you from doing harm to your data.

这篇关于IntegrityError:删除后违反外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆