Perché scaricare se puoi impegnarti?
Essendo qualcuno che non ha mai lavorato con database e sqlalchemy, le risposte precedenti - che flush()
inviano istruzioni SQL al DB e le commit()
persistono - non mi erano chiare. Le definizioni hanno un senso, ma non è immediatamente chiaro dalle definizioni il motivo per cui dovresti usare un flush invece di impegnarti.
Poiché un commit arrossisce sempre ( https://docs.sqlalchemy.org/en/13/orm/session_basics.html#committing ) questi suoni sono molto simili. Penso che il grosso problema da evidenziare sia che un flush non è permanente e può essere annullato, mentre un commit è permanente, nel senso che non si può chiedere al database di annullare l'ultimo commit (penso)
@snapshoe evidenzia che se si desidera eseguire una query sul database e ottenere risultati che includono oggetti appena aggiunti, è necessario aver prima scaricato (o eseguito il commit, che scaricherà per voi). Forse questo è utile per alcune persone, anche se non sono sicuro del motivo per cui vorresti svuotare piuttosto che impegnarti (a parte la banale risposta che può essere annullata).
In un altro esempio stavo sincronizzando i documenti tra un DB locale e un server remoto e, se l'utente ha deciso di annullare, tutte le aggiunte / gli aggiornamenti / le eliminazioni dovrebbero essere annullate (ovvero nessuna sincronizzazione parziale, solo una sincronizzazione completa). Durante l'aggiornamento di un singolo documento ho deciso di eliminare semplicemente la vecchia riga e aggiungere la versione aggiornata dal server remoto. Si scopre che a causa del modo in cui viene scritta sqlalchemy, l'ordine delle operazioni durante il commit non è garantito. Ciò ha comportato l'aggiunta di una versione duplicata (prima di tentare di eliminare quella precedente), che ha comportato il fallimento di un vincolo univoco nel DB. Per flush()
ovviare a questo ho usato in modo che l'ordine fosse mantenuto, ma potevo ancora annullare se in seguito il processo di sincronizzazione non fosse riuscito.
Vedi il mio post su questo su: Esiste un ordine per aggiungere o eliminare quando si commette in sqlalchemy
Allo stesso modo, qualcuno voleva sapere se viene mantenuto l'ordine di aggiunta durante il commit, ovvero se aggiungo object1
quindi aggiungi object2
, object1
viene aggiunto al database prima che object2
SQLAlchemy salvi l'ordine quando si aggiungono oggetti alla sessione?
Ancora una volta, qui presumibilmente l'uso di un flush () garantirebbe il comportamento desiderato. Quindi, in sintesi, un uso di flush è quello di fornire garanzie di ordine (credo), pur concedendosi ancora un'opzione di "annullamento" che il commit non fornisce.
Autoflush e Autocommit
Nota, l'autoflush può essere utilizzato per garantire che le query agiscano su un database aggiornato poiché sqlalchemy scaricherà prima di eseguire la query. https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session.params.autoflush
L'autocommit è qualcos'altro che non capisco completamente ma sembra che il suo uso sia scoraggiato:
https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session.params. autocommit
Utilizzo della memoria
Ora la domanda originale in realtà voleva sapere sull'impatto di flush vs. commit a fini di memoria. Dato che la capacità di persistere o meno è qualcosa che il database offre (penso), il semplice flushing dovrebbe essere sufficiente per scaricare nel database - anche se il commit non dovrebbe danneggiare (in realtà probabilmente aiuta - vedi sotto) se non ti interessa annullare .
sqlalchemy usa riferimenti deboli per oggetti che sono stati scaricati: https://docs.sqlalchemy.org/en/13/orm/session_state_management.html#session-referencing-behavior
Questo significa che se non hai un oggetto esplicitamente tenuto da qualche parte, come in un elenco o in un dict, sqlalchemy non lo manterrà in memoria.
Tuttavia, allora hai il lato database delle cose di cui preoccuparti. Presumibilmente il flushing senza impegno comporta una penalità di memoria per mantenere la transazione. Ancora una volta, sono nuovo a questo, ma ecco un link che sembra suggerire esattamente questo: https://stackoverflow.com/a/15305650/764365
In altre parole, i commit dovrebbero ridurre l'utilizzo della memoria, sebbene presumibilmente ci sia un compromesso tra memoria e prestazioni qui. In altre parole, probabilmente non si desidera eseguire il commit di ogni singola modifica del database, una alla volta (per motivi di prestazioni), ma attendere troppo a lungo aumenterà l'utilizzo della memoria.