Source code for aeat.adapters.persistence.storage.sql.session
"""Session and unit-of-work helpers for the SQL persistence layer.Thin wrappers around :class:`sqlalchemy.orm.sessionmaker` that enforcecommit-on-success and rollback-on-exception semantics via a contextmanager. Pairs with :func:`adapters.persistence.storage.sql.engine.get_engine`to provide a default binding when callers do not pass an explicitengine."""from__future__importannotationsfromcollections.abcimportIteratorfromcontextlibimportcontextmanagerfromsqlalchemyimportEnginefromsqlalchemy.ormimportSession,sessionmakerfrom.....core.loggingimportget_loggerfrom.engineimportget_engine_log=get_logger(__name__)
[docs]defget_sessionmaker(engine:Engine|None=None)->sessionmaker[Session]:"""Return a :class:`~sqlalchemy.orm.sessionmaker` bound to ``engine``. Args: engine: Optional engine override. When ``None``, :func:`get_engine` is consulted. Returns: A configured :class:`sessionmaker` instance. """returnsessionmaker(bind=engineorget_engine(),expire_on_commit=False,future=True)
[docs]@contextmanagerdefsession_scope(engine:Engine|None=None)->Iterator[Session]:"""Context-managed unit of work. Commits on normal exit, rolls back on exception, and always closes the session. Args: engine: Optional engine override. When ``None``, :func:`get_engine` is consulted. Yields: A live :class:`~sqlalchemy.orm.Session`. Raises: Exception: Re-raised after rolling back when the session body raises. """factory=get_sessionmaker(engine)session=factory()try:yieldsessionsession.commit()exceptException:# rollback on any error then re-raise; SQLAlchemy exception surface is too broad to enumerate_log.debug("session_scope rolling back due to exception",exc_info=True)session.rollback()raisefinally:session.close()