2010-11-17 11 views
13

El método create() en Django crea una instancia de modelo y luego llama a save(), que se dice que desencadena la confirmación. Por lo tanto, no debería haber ninguna diferencia al activar la confirmación de la transacción.Django: diferencia entre save() y create() desde la perspectiva de transacción

Pero en realidad, al ejecutar un método que crea un conjunto de instancias de modelo usando create() en Postgresql recibo la excepción transaction aborted, commands ignored until end of transaction. El método funciona bien con back-ends db no transaccionales. Además, cuando reemplazo el create() s por:

m = Model(attr1=..., attr2=...) 
m.save() 

funciona también en Postgresql.

¿Hay alguna diferencia entre usar save() y create() en el sentido de transacciones?

edit: create() también establece self._for_write = True antes de llamar a save(), pero no pude rastrearlo para ver si tiene algún efecto en el comportamiento de la transacción.

edición: código de ejemplo se puede encontrar here.

Respuesta

12

Como usted probablemente ha visto, create() is just a wrapper for save():

El _for_write part es muy probablemente destinados sólo para la selección de bases de datos, por lo que no habría prestar demasiada atención a ella.

Y con respecto a ese error de "transacción abortada", sin ver su código es difícil decir cuál es el problema. Tal vez, por ejemplo, violó la restricción ÚNICA con create(), lo que hace que PostgreSQL exija la reversión de transacción, y luego probó save() con datos diferentes, es difícil de decir sin el código exacto.

+0

gracias por la respuesta. Agregué un enlace a un código de ejemplo a la pregunta. por favor, avíseme si una aclaración adicional ayudaría. – omat

+0

Podría haber algún problema transaccional como éste: http://stackoverflow.com/questions/2235318/how-do-i-deal-with-this-race-condition-in-django/2235624#2235624 (tenga en cuenta que se trata de MySQL-specific), pero mirando su código veo que las dos versiones no son equivalentes: la versión de trabajo 'get() s' por' slug' y 'create() s' con' name', mientras que la otra versión ' create() s' con 'name' ** y **' slug'. Entonces quizás esta asimetría esté detrás del problema. –

Cuestiones relacionadas