from collections.abc import Iterator from sqlalchemy import create_engine, event from sqlalchemy.orm import Session, sessionmaker from app.core.config import settings _is_sqlite = settings.database_url.startswith("sqlite") _connect_args = {"check_same_thread": False, "timeout": 30} if _is_sqlite else {} engine = create_engine( settings.database_url, pool_pre_ping=True, future=True, connect_args=_connect_args, ) if _is_sqlite: # WAL: reader 와 writer 가 공존(테스트의 eager worker 동시 쓰기 데드락 방지). # 운영(Postgres)에는 영향 없음. @event.listens_for(engine, "connect") def _sqlite_pragmas(dbapi_conn, _record): # pragma: no cover cur = dbapi_conn.cursor() cur.execute("PRAGMA journal_mode=WAL") cur.execute("PRAGMA busy_timeout=30000") cur.close() SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False, future=True) def get_db() -> Iterator[Session]: """FastAPI 의존성: 요청 단위 DB 세션.""" db = SessionLocal() try: yield db finally: db.close()