2010-03-30 13 views
5

Tengo el modelo de pedido y envío. El envío tiene una clave externa para ordenar.IntegrityError: violación de clave externa al eliminar

class Order(...): 
    ... 

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

Ahora en una de mis vistas quiero eliminar el objeto de orden junto con todos los objetos relacionados. Entonces invoco order.delete().

Tengo Django 1.0.4, PostgreSQL 8.4 y uso el middleware de transacciones, por lo que toda la solicitud se adjunta en una sola transacción.

El problema es que al order.delete() me sale:

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

me registré connection.queries que las consultas apropiadas se ejecutan en el orden correcto. Se suprime el primer envío, después de que Django ejecuta borrar en el corredor de orden:

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

Clave externa en Utilizar DELETE NO ACTION (por defecto) y se aplazó inicialmente. No sé por qué recibo una violación de restricción de clave externa.

También intenté registrar la señal de pre_delete y eliminar manualmente los objetos de envío antes de llamar a la orden delete, pero resultó en el mismo error.

Puedo cambiar el comportamiento ON DELETE para esta clave en Postgres pero sería solo un truco, me pregunto si alguien tiene una mejor idea de lo que está sucediendo aquí.

También hay un pequeño detalle, mi modelo de pedido hereda del modelo Cart, por lo que realmente no tiene el campo id pero cart_ptr_id y después de que se ejecuta DELETE en el pedido también está ELIMINADO en el carrito, pero parece no estar relacionado. al problema de envío-> orden, así que lo simplifiqué en el ejemplo.

+0

Bueno, probé esto en la consola psql, y el mismo resultado, por lo que es estrictamente postgreql. Maybye no entiendo cómo funciona el diferido. –

+0

¿Podría proporcionar una tabla de creación relevante SQL? – Unreason

+0

¿Por qué está borrando pedidos que tienen envíos? En general, esto es algo que te gustaría fallar. No desea eliminar envíos reales, nunca. – HLGEM

Respuesta

4

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

todavía hay un registro de referencia de Identificación 45. Usted haya eliminado ficha 17 en main_shipment antes, pero puede haber otros también. Debe eliminar todos los registros en main_shipment haciendo referencia a id 45 en main_order. De lo contrario, la base de datos lo protege de dañar sus datos.

+0

Ahhhhhh:/Estuve peleando con él tanto tiempo y me acabo de dar cuenta de que más adelante en el código python, en el bloque de código superior, tengo shipment.save():/Y no lo noté en la salida de conn.queries porque era impreso antes de llamar a send.save(). –

Cuestiones relacionadas