2010-03-30 17 views
5

Sipariş ve Gönderi modelim var. Gönderinin Sipariş için bir yabancı anahtarı var.IntegrityError: Silme sonrasında yabancı anahtar ihlali

class Order(...): 
    ... 

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

Şimdi görünümlerimden birinde, ilgili tüm nesnelerle birlikte sipariş nesnesini silmek istiyorum. Bu yüzden order.delete() 'yi çağırıyorum.

Django 1.0.4, PostgreSQL 8.4 sahibiyim ve işlem ara katman yazılımını kullanıyorum, bu nedenle tüm istek tek bir işlemle kapatılıyor. Ben doğru sorgular doğru sırayla yürütülür olduğunu connection.queries kontrol

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

:

sorun order.delete üzerine() alıyorum olmasıdır.

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

Yabancı anahtar YOK EYLEM (varsayılan) SİL AÇIK olması ve başlangıçta ertelenir: İlk sevkiyat o django sipariş satırda silmek yürütür sonra silinir. Yabancı anahtar kısıtlama ihlali neden aldığımı bilmiyorum.

Ayrıca, pre_delete sinyalini kaydetmeyi denedim ve siparişte silme işleminden önce sevkiyat nesnelerini el ile silmeyi denedim, ancak aynı hatayla sonuçlandı.

PostGres'de bu tuş için SİLME davranışını değiştirebilirim, ancak sadece bir kesmek olurdu, merak ediyorum, burada neler olup bittiği hakkında daha iyi bir fikriniz varsa.

Ayrıca küçük bir detay, Sipariş modelimin Sepeti modelinden miras alması, yani kimlik alanı yok, ancak cart_ptr_id yok ve siparişte DELETE yapıldıktan sonra da sepette DELETE var, ama alakasız görünüyor? gönderi-> sipariş sorununa bu yüzden örnekte basitleştirdim.

+0

Bunu psql konsolunda ve aynı sonucu denedim, bu yüzden kesinlikle postgreql maddesidir. Maybye, nasıl ertelenmiş işe yaramıyor. –

+0

İlgili oluşturma tablosu SQL'i sağlayabilir misiniz? – Unreason

+0

Gönderileri olan siparişleri neden silmiyorsunuz? Genel olarak bu, başarısız olmak isteyeceğiniz bir şeydir. Asla gerçek gönderileri silmek istemezsiniz. – HLGEM

cevap

4

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

hala daha önce main_shipment rekoru 17 sildin id 45. üzere çözümleyici bir kayıt olmalı, ama aynı zamanda başkaları da olabilir. Main_shipment'daki tüm kayıtları main_order'de id 45'e referansla silmeniz gerekir. Aksi takdirde veritabanı verilerinize zarar vermenizi önler.

+0

Ahhhhhh:/Onunla çok uzun bir süredir kavga ettim ve daha sonra python kodunda, daha yüksek kod bloğunda, shipment.save() olduğunu fark ettim:/Ve bunu conn.queries çıkışında fark etmedim çünkü shipment.save() den önce yazdırılır. –