"""Database connection and session management.""" from contextlib import asynccontextmanager from typing import AsyncGenerator from sqlalchemy.ext.asyncio import ( AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine, ) from app.infrastructure.config import settings # Convert SQLite URL to async format if needed def _get_database_url() -> str: url = settings.database_url if url.startswith("sqlite:///") and not url.startswith("sqlite+aiosqlite:///"): return url.replace("sqlite:///", "sqlite+aiosqlite:///") return url # Create async engine engine: AsyncEngine = create_async_engine( _get_database_url(), echo=settings.database_echo, future=True, ) # Create session factory AsyncSessionLocal = async_sessionmaker( engine, class_=AsyncSession, expire_on_commit=False, autoflush=False, autocommit=False, ) async def get_session() -> AsyncGenerator[AsyncSession, None]: """Get database session.""" async with AsyncSessionLocal() as session: try: yield session finally: await session.close() @asynccontextmanager async def get_session_context() -> AsyncGenerator[AsyncSession, None]: """Get database session as context manager.""" async with AsyncSessionLocal() as session: try: yield session finally: await session.close() async def init_db() -> None: """Initialize database tables.""" from app.infrastructure.database.models import Base async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) async def close_db() -> None: """Close database connections.""" await engine.dispose()