¿Por qué enjuagarse si puedes comprometerte?
Como alguien nuevo en trabajar con bases de datos y sqlalchemy, las respuestas anteriores, que flush()
envían declaraciones SQL a la base de datos y las commit()
persisten, no me quedaron claras. Las definiciones tienen sentido, pero las definiciones no aclaran de inmediato por qué usaría una descarga en lugar de solo comprometerse.
Dado que una confirmación siempre se vacía ( https://docs.sqlalchemy.org/en/13/orm/session_basics.html#committing ), esto suena muy similar. Creo que el gran problema a destacar es que una descarga no es permanente y se puede deshacer, mientras que un commit es permanente, en el sentido de que no se puede pedir a la base de datos que deshaga el último commit (creo)
@snapshoe destaca que si desea consultar la base de datos y obtener resultados que incluyan objetos recién agregados, primero debe enjuagarse (o confirmarse, lo que enjuagará por usted). Tal vez esto sea útil para algunas personas, aunque no estoy seguro de por qué querría enjuagarse en lugar de comprometerse (aparte de la respuesta trivial de que se puede deshacer).
En otro ejemplo, estaba sincronizando documentos entre una base de datos local y un servidor remoto, y si el usuario decidía cancelar, todas las adiciones / actualizaciones / eliminaciones deberían deshacerse (es decir, sin sincronización parcial, solo una sincronización completa). Al actualizar un solo documento, he decidido simplemente eliminar la fila anterior y agregar la versión actualizada del servidor remoto. Resulta que, debido a la forma en que se escribe sqlalchemy, el orden de las operaciones cuando se confirma no está garantizado. Esto resultó en la adición de una versión duplicada (antes de intentar eliminar la anterior), lo que provocó que el DB fallara una restricción única. Para solucionar esto, utilicé flush()
para mantener el orden, pero aún podía deshacerlo si luego el proceso de sincronización fallaba.
Vea mi publicación sobre esto en: ¿Hay algún orden para agregar versus eliminar cuando se confirma en sqlalchemy
Del mismo modo, alguien quería saber si el orden de agregar se mantiene cuando se confirma, es decir, si agrego y object1
luego agrego object2
, ¿ object1
se agrega a la base de datos antes? object2
¿SQLAlchemy guarda el orden al agregar objetos a la sesión?
De nuevo, aquí presumiblemente el uso de flush () aseguraría el comportamiento deseado. En resumen, un uso para flush es proporcionar garantías de orden (creo), de nuevo mientras se permite una opción de "deshacer" que commit no proporciona.
Autoflush y Autocommit
Tenga en cuenta que el enjuague automático se puede usar para garantizar que las consultas actúen en una base de datos actualizada, ya que sqlalchemy se enjuagará antes de ejecutar la consulta. https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session.params.autoflush
La confirmación automática es algo más que no entiendo completamente, pero parece que se desaconseja su uso:
https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session.params. confirmación automática
Uso de memoria
Ahora la pregunta original realmente quería saber sobre el impacto de flush vs. commit para propósitos de memoria. Como la capacidad de persistir o no es algo que ofrece la base de datos (creo), simplemente el enjuague debería ser suficiente para descargar en la base de datos, aunque el compromiso no debería dañar (en realidad probablemente ayude, ver a continuación) si no le importa deshacer .
sqlalchemy utiliza referencias débiles para objetos que se han vaciado: https://docs.sqlalchemy.org/en/13/orm/session_state_management.html#session-referencing-behavior
Esto significa que si no tiene un objeto retenido explícitamente en algún lugar, como en una lista o dict, sqlalchemy no lo guardará en la memoria.
Sin embargo, entonces tiene que preocuparse por el lado de la base de datos. Presumiblemente, el vaciado sin comprometer viene con una penalización de memoria para mantener la transacción. Nuevamente, soy nuevo en esto, pero aquí hay un enlace que parece sugerir exactamente esto: https://stackoverflow.com/a/15305650/764365
En otras palabras, los commits deberían reducir el uso de memoria, aunque presumiblemente hay una compensación entre memoria y rendimiento aquí. En otras palabras, probablemente no desee confirmar cada cambio de base de datos, uno a la vez (por razones de rendimiento), pero esperar demasiado aumentará el uso de memoria.