2010-11-17 14 views
13

Il metodo create() in Django crea un'istanza del modello, quindi chiama save(), che si dice attiva il commit. Quindi non dovrebbe esserci alcuna differenza nell'attivazione del commit della transazione.Django: Differenza tra save() e create() dal punto di vista della transazione

Ma in realtà, l'esecuzione di un metodo che crea un gruppo di istanze di modelli utilizzando create() su Postgresql mi viene restituita dall'eccezione transaction aborted, commands ignored until end of transaction. Il metodo funziona correttamente con i backb db non transazionali. Inoltre, quando si sostituisce la creo() s con:

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

funziona su PostgreSQL troppo bene.

C'è una differenza tra l'utilizzo di save() e create() nel senso delle transazioni?

modifica: create() imposta anche self._for_write = True prima di chiamare save(), ma non è stato possibile rintracciarlo per vedere se ha qualche effetto sul comportamento della transazione.

modifica: codice di esempio può essere trovato here.

risposta

12

Come probabilmente avete visto, create() is just a wrapper for save():

Il _for_write part è molto probabilmente significava solo per selezione del database, in modo da non prestare troppa attenzione ad esso.

E per quanto riguarda l'errore "transazione interrotta", senza vedere il tuo codice è difficile dire qual è il problema. Forse tu ad es. violato il vincolo UNIQUE con create(), che fa sì che PostgreSQL richieda il rollback della transazione, e quindi hai provato save() con dati diversi - è difficile dirlo senza il codice esatto.

+0

grazie per la risposta. ho aggiunto il link a un codice di esempio alla domanda. per favore fatemi sapere se ulteriori chiarimenti potrebbero aiutare. – omat

+0

Potrebbe trattarsi di un problema di transazione come questo: http://stackoverflow.com/questions/2235318/how-do-i-deal-with-this-race-condition-in-django/2235624#2235624 (nota che è MySQL-specifico), ma guardando il tuo codice vedo che le due versioni non sono equivalenti: la versione funzionante 'get() s' di' slug' e 'create() s' con' name', mentre l'altra versione ' create() s' con 'name' ** e **' slug'. Quindi forse questa asimmetria è dietro il problema. –

Problemi correlati