from typing import AsyncGenerator from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession from sqlalchemy.orm import declarative_base from backend.app.core.config import settings from backend.app.core.logger import logger # Build engine with appropriate connect_args depending on SQLite or PostgreSQL connect_args = {} engine_kwargs = {"echo": False, "future": True} if settings.DATABASE_URL.startswith("sqlite"): connect_args["check_same_thread"] = False else: engine_kwargs.update({ "pool_size": 10, "max_overflow": 20, "pool_pre_ping": True, }) engine = create_async_engine( settings.DATABASE_URL, connect_args=connect_args, **engine_kwargs, ) AsyncSessionLocal = async_sessionmaker( bind=engine, class_=AsyncSession, expire_on_commit=False, autocommit=False, autoflush=False, ) Base = declarative_base() async def get_db() -> AsyncGenerator[AsyncSession, None]: async with AsyncSessionLocal() as session: try: yield session except Exception as ex: await session.rollback() logger.error(f"Database session error: {ex}") raise finally: await session.close() async def init_db() -> None: """Initialize database tables for development/testing.""" async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) logger.info("Database schema initialized.")