"""Database engine/session setup. Each `Database` instance owns its own engine and session factory, so a production run and a test can each get a fully isolated database instead of sharing process-global state (see `main.create_app`). """ from __future__ import annotations import os from typing import Iterator, Optional from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker from .models import Base DEFAULT_DATABASE_URL = "sqlite:///./labeling.db" class Database: def __init__(self, database_url: Optional[str] = None): self.url = database_url or os.environ.get("DATABASE_URL", DEFAULT_DATABASE_URL) connect_args = {"check_same_thread": False} if self.url.startswith("sqlite") else {} self.engine = create_engine(self.url, connect_args=connect_args) self.session_factory = sessionmaker(autocommit=False, autoflush=False, bind=self.engine) def init_models(self) -> None: Base.metadata.create_all(bind=self.engine) def get_session(self) -> Iterator[Session]: session = self.session_factory() try: yield session finally: session.close() def get_db() -> Iterator[Session]: """Marker dependency; `create_app` overrides this with a real `Database.get_session`.""" raise NotImplementedError("get_db must be overridden via app.dependency_overrides")