Domanda

Ho riscontrato un semplice problema in SQLAlchemy. Ho un modello in una tabella, chiamiamolo Model1 qui. Voglio aggiungere una riga in questa tabella e ottenere la chiave autoincrementata, in modo da poter creare un altro modello con essa e utilizzare questa chiave. Questo non è un progetto di database difettoso (relazione 1: 1 ecc.). Ho semplicemente bisogno di questa chiave in un'altra tabella, perché l'altra tabella viene trasferita su un host remoto e ho bisogno delle chiavi corrispondenti in modo che i server si capiscano. Non ci saranno ulteriori riferimenti locali tra queste 2 tabelle e non è nemmeno possibile creare relazioni a causa di ciò.

Considera il seguente codice:

object1 = model.Model1(param)
DBSession.add(object1)

# if I do this, the line below fails with an UnboundExecutionError.
# and if I dont do this, object1.id won't be set yet
#transaction.commit()

object2 = model.AnotherModel(object1.id) #id holds the primary, autoincremented key

Avrei voluto non dover nemmeno impegnare " manualmente " ;. Fondamentalmente quello che vorrei ottenere è "Model1" è in costante crescita, con l'aumento della chiave primaria Model.id. AnotherModel è sempre solo una piccola parte di Model1, che non è stato ancora elaborato. Ovviamente potrei aggiungere un flag in "Model1", un campo booleano nella tabella per contrassegnare gli elementi già elaborati, ma speravo che ciò non fosse necessario.

Come posso far funzionare il mio codice sopra?

saluta,

Tom

È stato utile?

Soluzione

Un paio di cose:

  • Potresti spiegare a cosa è legata la variabile transazione ?
  • Esattamente quale affermazione genera UnboundExecutionError?
  • Fornisci il messaggio di eccezione completo, inclusa la traccia dello stack.
  • La cosa 'normale' da fare in questo caso sarebbe quella di chiamare DBSession.flush () . Ci hai provato?

Esempio:

object1 = Model1(param)
DBSession.add(object1)
DBSession.flush()
assert object1.id != None # flushing the session populates the id

object2 = AnotherModel(object1.id)

Per una grande spiegazione della sessione SA e cosa fa flush () , vedi Uso della sessione .

Fondamentalmente, flush () fa diventare persistenti le istanze in sospeso, il che significa che i nuovi oggetti sono INSERITI nelle tabelle del database. flush () aggiorna anche le tabelle con valori per le istanze che la sessione tiene traccia delle modifiche.

commit () emette sempre prima flush () .

All'interno di una transazione, puoi scaricare più volte. Ogni flush () provoca UPDATE e / o INSERT nel database. È possibile eseguire il commit o il rollback dell'intera transazione.

Altri suggerimenti

se vuoi ottenere nuovi identificatori di chiavi primarie da generare senza alcun impegno, chiama session.flush (). Ciò emetterà tutto ciò che è in sospeso nel database all'interno della transazione corrente.

L'ho usato solo con ForeignKeys, quindi nel secondo caso preferiresti fare model.AnotherModel (model1 = object1), e poi ha funzionato (tm). Quindi ho il sospetto che questo potrebbe essere un problema con i tuoi modelli, quindi forse potresti pubblicarli anche tu?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top