sessionmaker()
es una fábrica, está ahí para alentar la colocación de opciones de configuración para crear nuevos objetos Session
en un solo lugar. Es opcional, en el sentido de que puede llamar al Session(bind=engine, expire_on_commit=False)
cada vez que necesite un nuevo Session
, excepto que es detallado y redundante, y quería detener la proliferación de "ayudantes" a pequeña escala que abordaban el problema de esta redundancia en una forma nueva y más confusa.
Así que sessionmaker()
es solo una herramienta para ayudarte a crear objetos Session
cuando los necesitas.
Siguiente parte. Creo que la pregunta es, ¿cuál es la diferencia entre hacer un nuevo Session()
en varios puntos en lugar de simplemente usar uno en todos los sentidos? La respuesta, no mucho. Session
es un contenedor para todos los objetos que pone en él, y luego también realiza un seguimiento de una transacción abierta. En el momento en que llame al rollback()
o al commit()
, la transacción ha finalizado y el Session
no tiene conexión con la base de datos hasta que se le solicite que emita SQL nuevamente. Los enlaces que contiene a los objetos asignados son referencias débiles, siempre que los objetos estén limpios de cambios pendientes, por lo que incluso en ese sentido, el Session
se vaciará a un nuevo estado cuando la aplicación pierda todas las referencias a objetos mapeados. Si lo deja con su configuración predeterminada "expire_on_commit"
, todos los objetos caducarán después de una confirmación. Si ese Session
se queda durante cinco o veinte minutos, y todo tipo de cosas han cambiado en la base de datos la próxima vez que lo use, cargará todos los nuevos estados la próxima vez que acceda a esos objetos aunque hayan estado sentados en memoria durante veinte minutos.
En las aplicaciones web, generalmente decimos, hey por qué no hace una nueva marca Session
en cada solicitud, en lugar de utilizar la misma una y otra vez. Esta práctica asegura que la nueva solicitud comienza "limpia". Si algunos objetos de la solicitud anterior aún no han sido recogidos basura, y si tal vez ha desactivado "expire_on_commit"
, tal vez algún estado de la solicitud anterior todavía está dando vueltas, y ese estado podría ser bastante viejo. Si tiene cuidado de dejar expire_on_commit
encendido y definitivamente llamar al commit()
o rollback()
al final de la solicitud, entonces está bien, pero si comienza con un nuevo Session
, entonces ni siquiera hay dudas de que está comenzando a limpiar.Entonces, la idea de comenzar cada solicitud con un nuevo Session
es realmente la manera más simple de asegurarse de que está comenzando de cero, y hacer que el uso de expire_on_commit
sea prácticamente opcional, ya que este indicador puede generar una gran cantidad de SQL adicionales para una operación que llama al commit()
en el medio de una serie de operaciones. No estoy seguro si esto responde tu pregunta.
La siguiente ronda es lo que mencionas sobre el enhebrado. Si su aplicación es multiproceso, le recomendamos que se asegure de que el Session
en uso sea local para ... algo. scoped_session()
por defecto lo hace local al hilo actual. En una aplicación web, lo local de la solicitud es, de hecho, incluso mejor. Flask-SQLAlchemy en realidad envía una "función de alcance" personalizada al scoped_session()
para que pueda obtener una sesión con alcance de solicitud. La aplicación Pyramid promedio pega la sesión en el registro de "solicitud". Cuando se utilizan esquemas como estos, la idea de "crear nueva sesión al inicio de la solicitud" sigue pareciendo la forma más directa de mantener las cosas en orden.
Guau, esto responde todas mis preguntas en la parte de SQLAlchemy e incluso agrega alguna información acerca de Flask a ¡nd Pyramid! Bonificación adicional: los desarrolladores responden;) Desearía poder votar más de una vez. ¡Muchas gracias! – javex
Una aclaración, si es posible: dices expire_on_commit "puede incurrir en un montón de SQL adicional" ... ¿puedes dar más detalles? Pensé que expire_on_commit solo se refería a lo que sucede en la RAM, no a lo que sucede en la base de datos. – Veky
expire_on_commit puede dar como resultado más SQL si vuelve a utilizar la misma sesión de nuevo, y algunos objetos todavía están dando vueltas en esa sesión, cuando accede a ellos obtendrá un SELECT de una sola fila para cada uno de ellos, ya que cada uno individualmente actualizar su estado en términos de la nueva transacción. – zzzeek