""" Database engine and session factory. We use SQLAlchemy 2.x with the "declarative" ORM style. All models should inherit from ``Base`` defined here. Session lifecycle: - ``get_db()`` is a FastAPI dependency that opens a session per request and guarantees it is closed (and rolled back on error) when the request ends. """ from sqlalchemy import create_engine from sqlalchemy.orm import DeclarativeBase, sessionmaker from app.config import settings # connect_args is SQLite-specific: it allows the same connection to be used # from multiple threads, which is required because FastAPI runs in a thread # pool. This flag is harmless / unused for PostgreSQL. _connect_args = ( {"check_same_thread": False} if settings.database_url.startswith("sqlite") else {} ) engine = create_engine(settings.database_url, connect_args=_connect_args) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) class Base(DeclarativeBase): """All ORM models inherit from this class.""" pass def get_db(): """ FastAPI dependency that yields a database session. Usage:: @router.get("/things") def list_things(db: Session = Depends(get_db)): ... """ db = SessionLocal() try: yield db finally: db.close() def create_tables(): """Create all tables that are registered on Base.metadata. Called once at application startup (see main.py). Safe to run multiple times – SQLAlchemy will not recreate existing tables. """ # Importing models here ensures they are registered on Base.metadata # before create_all() is called. import app.models.user # noqa: F401 import app.models.item # noqa: F401 Base.metadata.create_all(bind=engine)