from __future__ import annotations from collections.abc import Iterator from sqlalchemy import Engine, create_engine from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker from ypms.settings import get_settings class Base(DeclarativeBase): pass _engine: Engine | None = None _SessionLocal: sessionmaker[Session] | None = None def engine() -> Engine: global _engine if _engine is None: # hide_parameters: keep bound values (PII) out of exception text and logs. _engine = create_engine( get_settings().database_url, pool_pre_ping=True, future=True, hide_parameters=True ) return _engine def session_factory() -> sessionmaker[Session]: global _SessionLocal if _SessionLocal is None: _SessionLocal = sessionmaker(bind=engine(), autoflush=False, autocommit=False, future=True) return _SessionLocal def get_db() -> Iterator[Session]: db = session_factory()() try: yield db finally: db.close()