2010-03-30 2 views
5

주문 및 배송 모델이 있습니다. 선적에는 주문에 대한 외래 키가 있습니다.IntegrityError : 삭제시 외래 키 위반

class Order(...): 
    ... 

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

내 의견에서 모든 관련 개체와 함께 주문 개체를 삭제하고 싶습니다. 그래서 나는 order.delete()를 호출했다.

Django 1.0.4, PostgreSQL 8.4가 있으며 트랜잭션 미들웨어를 사용하므로 전체 요청은 단일 트랜잭션으로 묶여 있습니다. 내가 적절한 쿼리가 올바른 순서로 실행되는 것을 connection.queries 체크

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

:

문제는 order.delete에() 내가 얻을 수 있다는 것입니다.

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

외래 키는 NO ACTION (기본값)을 삭제하지 ON하고 초기에 지연됩니다 : 첫 선적은 장고는 주문 행을 삭제 실행 후 삭제됩니다. 왜 외래 키 제약 조건 위반을하는지 모르겠습니다.

또한 pre_delete 신호를 등록하고 주문에서 삭제하기 전에 선적 객체를 수동으로 삭제하려고했지만 동일한 오류가 발생했습니다.

Postgres에서이 키에 대한 삭제 동작을 변경할 수는 있지만 해킹 일뿐입니다. 여기에 무슨 일이 일어나고 있는지 더 잘 알고있는 사람이 있는지 궁금합니다.

내 세부 모델도 Cart 모델에서 상속되므로 실제로 id 필드가 없지만 cart_ptr_id가 있고 주문 DELETE가 실행 된 후에도 카트에는 DELETE가 있지만 관계가없는 것처럼 보입니까? shipment-> order 문제로 넘어 가서 예제에서 간략화했습니다.

+0

글쎄, 나는 psql 콘솔에서 이것을 시도해 보았다. 그리고 똑같은 결과가 나온다. 그래서 그것은 엄격하게 postgreql 문제이다. Maybye 나는 연기 된 작품을 얻지 못한다. –

+0

관련 테이블 작성 SQL을 제공 할 수 있습니까? – Unreason

+0

발송물이있는 주문을 삭제 하시겠습니까? 일반적으로 이것은 실패하려는 것입니다. 실제 발송물을 삭제하지 않으려 고합니다. – HLGEM

답변

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 :/나는 너무 오랫동안 그걸로 싸우고 있었고, 나중에 파이썬 코드에서, 더 높은 코드 블록에서, 나는 shipment.save()를 가지고 있다는 것을 깨달았다./conn.queries 결과에서 그것을 알아 채지 못했다. shipment.save()가 호출되기 전에 인쇄됩니다. –