"""SQLAlchemy engine and session factory.""" from __future__ import annotations from collections.abc import Iterator from contextlib import contextmanager from sqlalchemy import create_engine from sqlalchemy.engine import Engine from sqlalchemy.orm import Session, sessionmaker from app.config import settings _engine: Engine | None = None _SessionFactory: sessionmaker[Session] | None = None def get_engine() -> Engine: global _engine if _engine is None: _engine = create_engine( settings.database_url, pool_pre_ping=True, pool_size=10, max_overflow=20, future=True, ) return _engine def get_session_factory() -> sessionmaker[Session]: global _SessionFactory if _SessionFactory is None: _SessionFactory = sessionmaker( bind=get_engine(), autoflush=False, autocommit=False, expire_on_commit=False, future=True, ) return _SessionFactory @contextmanager def session_scope() -> Iterator[Session]: """Provide a transactional scope: commits on success, rolls back on error.""" factory = get_session_factory() session = factory() try: yield session session.commit() except Exception: session.rollback() raise finally: session.close() def get_db() -> Iterator[Session]: """FastAPI dependency.""" factory = get_session_factory() session = factory() try: yield session finally: session.close()