La mia applicazione consente agli utenti di creare ed eliminare oggetti Site
. L'ho implementato utilizzando session.add()
e session.delete()
. Poi ho i pulsanti 'Salva' e 'Ripristina' che chiamano session.commit()
e session.rollback()
.Eliminazione di un oggetto da una sessione SQLAlchemy prima che sia persistuto
Se aggiungo un nuovo Site
, quindi lo salvo/lo impegno e quindi lo elimino, tutto va bene. Tuttavia, se provo a rimuovere un oggetto dalla sessione prima che sia stato salvato, viene visualizzato un errore "non persistente".
Codice:
self.newSite = Site('foo')
self.session.add(self.newSite)
print self.session.new
self.session.delete(self.newSite)
uscita:
IdentitySet([<Site('foo')>])
Traceback (most recent call last):
File "C:\Program Files\Eclipse\dropins\plugins\org.python.pydev.debug_2.2.1.2011071313\pysrc\pydevd_comm.py", line 744, in doIt
result = pydevd_vars.evaluateExpression(self.thread_id, self.frame_id, self.expression, self.doExec)
File "C:\Program Files\Eclipse\dropins\plugins\org.python.pydev.debug_2.2.1.2011071313\pysrc\pydevd_vars.py", line 375, in evaluateExpression
result = eval(compiled, updated_globals, frame.f_locals)
File "<string>", line 1, in <module>
File "C:\Python27\Lib\site-packages\sqlalchemy\orm\session.py", line 1245, in delete
mapperutil.state_str(state))
InvalidRequestError: Instance '<Site at 0x1ed5fb0>' is not persisted
capisco cosa sta succedendo qui, ma non sono sicuro di quello che dovrei fare, invece.
Esiste un altro metodo per rimuovere un oggetto non ancora persistuto da una sessione? O dovrei chiamare lo session.flush()
prima di tentare una cancellazione, nel caso in cui l'oggetto che voglio cancellare non sia stato ancora scaricato?
Se si tratta di quest'ultimo, come mai session.query()
auto-vampate (garantire che gli oggetti in sospeso visualizzati nei risultati della query), ma non lo fa session.delete()
(che garantirebbe che gli oggetti in sospeso possono essere cancellati senza errori).
Sono d'accordo con Mike sul fatto che 'delete' potrebbe essere più indulgente. Tuttavia, la situazione attuale è molto semplificata - potrebbero esserci altri oggetti correlati che sono stati esplicitamente o implicitamente (tramite relazioni) aggiunti alla stessa sessione e non commessi. Pertanto, IMO, il modo più pulito è eseguire un 'rollback()' sulla sessione. – van
Grazie, ora ha senso. Quindi, quando si fa clic sul pulsante Elimina, quale dovrebbe essere la logica? Qualcosa come 'try: session.delete (foo); tranne InvalidRequestError: session.expunge (foo) '? Oppure, come da [questa risposta] (http://stackoverflow.com/a/3897845/665488), forse: 'if has_identity (foo): session.delete (foo); else: session.expunge (foo) '? –
Probabilmente direi "se oggetto in session.new: expunge else: delete" – zzzeek