from collections.abc import AsyncIterator from functools import lru_cache from sqlalchemy import event from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine from app.core.config import get_settings @lru_cache(maxsize=1) def create_engine() -> AsyncEngine: settings = get_settings() engine = create_async_engine(settings.database_url, future=True) @event.listens_for(engine.sync_engine, "connect") def _set_sqlite_pragma(dbapi_connection, _connection_record) -> None: cursor = dbapi_connection.cursor() cursor.execute("PRAGMA foreign_keys=ON") cursor.close() return engine def create_session_factory() -> async_sessionmaker[AsyncSession]: return async_sessionmaker(create_engine(), class_=AsyncSession, expire_on_commit=False) async def get_db_session() -> AsyncIterator[AsyncSession]: session_factory = create_session_factory() async with session_factory() as session: yield session async def dispose_engine() -> None: engine = create_engine() await engine.dispose() create_engine.cache_clear()