2010-03-30 21 views
5

Ho un modello di ordine e spedizione. La spedizione ha una chiave esterna da ordinare.IntegrityError: violazione della chiave esterna all'eliminazione

class Order(...): 
    ... 

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

Ora in una delle mie viste voglio eliminare l'oggetto ordine insieme a tutti gli oggetti correlati. Quindi invoco order.delete().

Ho Django 1.0.4, PostgreSQL 8.4 e utilizzo il middleware delle transazioni, quindi l'intera richiesta è racchiusa in un'unica transazione.

Il problema è che al momento order.delete() ottengo:

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

ho controllato connection.queries che le query appropriate vengono eseguiti in ordine corretto. In primo luogo la spedizione viene eliminato, dopo che Django esegue cancellare nel braccio ordine:

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

chiave degli Esteri hanno su DELETE NO ACTION (default) ed è inizialmente differita. Non so perché ottengo violazione dei vincoli di chiave esterna.

Ho anche provato a registrare il segnale pre_delete e manualmente eliminare gli oggetti di spedizione prima che venga cancellato all'ordine, ma ha provocato lo stesso errore.

Posso modificare il comportamento ON DELETE per questo tasto in Postgres ma sarebbe solo un trucco, mi chiedo se qualcuno ha un'idea migliore di cosa sta succedendo qui.

C'è anche un piccolo dettaglio, il mio modello Ordine eredita dal modello Cart, quindi in realtà non ha campo id ma cart_ptr_id e dopo che DELETE su ordine viene eseguito c'è anche DELETE sul carrello, ma sembra non correlato? al problema della spedizione-> così l'ho semplificato nell'esempio.

+0

Beh, ho provato questo in console psql, e lo stesso risultato, quindi è materia rigorosamente postgreql. Arrivederci Non capisco come differisce il lavoro. –

+0

Potrebbe fornire l'SQL della tabella di creazione pertinente? – Unreason

+0

Per quale motivo si eliminano gli ordini con spedizioni? Generalmente questo è qualcosa che vorresti fallire. Non si desidera eliminare le spedizioni effettive, mai. – HLGEM

risposta

4

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

c'è ancora un record di riferimento per id 45. hai eliminato record di 17 nel main_shipment prima, ma ci potrebbero essere anche altri. Devi eliminare tutti i record in main_shipment facendo riferimento a id 45 in main_order. In caso contrario, il database ti protegge da eventuali danni ai tuoi dati.

+0

Ahhhhhh:/Ci stavo combattendo così a lungo e ho appena realizzato che più tardi in codice Python, in un blocco di codice superiore, ho shipment.save():/E non l'ho notato nell'output conn.queries perché era stampato prima della spedizione.save() viene chiamato. –

Problemi correlati