""" Database configuration and connection setup for the Virtual Board Member AI System. """ import asyncio from typing import AsyncGenerator from sqlalchemy import create_engine, MetaData from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.pool import StaticPool import structlog from app.core.config import settings logger = structlog.get_logger() # Create async engine async_engine = create_async_engine( settings.DATABASE_URL.replace("postgresql://", "postgresql+asyncpg://"), echo=settings.DEBUG, pool_size=settings.DATABASE_POOL_SIZE, max_overflow=settings.DATABASE_MAX_OVERFLOW, pool_timeout=settings.DATABASE_POOL_TIMEOUT, pool_pre_ping=True, ) # Create sync engine for migrations sync_engine = create_engine( settings.DATABASE_URL, echo=settings.DEBUG, poolclass=StaticPool if settings.TESTING else None, ) # Create session factory AsyncSessionLocal = async_sessionmaker( async_engine, class_=AsyncSession, expire_on_commit=False, ) # Create base class for models Base = declarative_base() # Metadata for migrations metadata = MetaData() async def get_db() -> AsyncGenerator[AsyncSession, None]: """Dependency to get database session.""" async with AsyncSessionLocal() as session: try: yield session except Exception as e: await session.rollback() logger.error("Database session error", error=str(e)) raise finally: await session.close() async def init_db() -> None: """Initialize database tables.""" try: async with async_engine.begin() as conn: # Import all models to ensure they are registered from app.models import user, document, commitment, audit_log # noqa # Create all tables await conn.run_sync(Base.metadata.create_all) logger.info("Database tables created successfully") except Exception as e: logger.error("Failed to initialize database", error=str(e)) raise async def close_db() -> None: """Close database connections.""" await async_engine.dispose() logger.info("Database connections closed") def get_sync_db(): """Get synchronous database session for migrations.""" return sync_engine # Database health check async def check_db_health() -> bool: """Check database connectivity.""" try: async with AsyncSessionLocal() as session: await session.execute("SELECT 1") return True except Exception as e: logger.error("Database health check failed", error=str(e)) return False