""" Database Configuration - ServiceManagerWeb SQLAlchemy 2.0 async setup con PostgreSQL """ from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from sqlalchemy import String, DateTime, func from typing import AsyncGenerator import uuid from datetime import datetime from app.core.config import get_settings settings = get_settings() # Create async engine engine = create_async_engine( settings.DATABASE_URL, echo=settings.DEBUG, pool_size=20, # Increased for better concurrency max_overflow=30, # Increased for peak loads pool_pre_ping=True, # Verify connections before use pool_recycle=3600, # Recycle connections after 1 hour pool_timeout=30, # Wait up to 30s for connection from pool ) # Create session factory AsyncSessionLocal = async_sessionmaker( engine, class_=AsyncSession, expire_on_commit=False, autoflush=True, autocommit=False ) class Base(DeclarativeBase): """Base class para todos los modelos SQLAlchemy.""" # Columnas comunes para auditoría id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), onupdate=func.now() ) async def get_db() -> AsyncGenerator[AsyncSession, None]: """ Dependency para obtener sesión de base de datos. Yields: AsyncSession: Sesión de base de datos """ async with AsyncSessionLocal() as session: try: yield session await session.commit() except Exception: await session.rollback() raise finally: await session.close() async def create_tables(): """Crear todas las tablas en desarrollo.""" async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) async def drop_tables(): """Eliminar todas las tablas (solo para testing).""" async with engine.begin() as conn: await conn.run_sync(Base.metadata.drop_all) # Health check function async def check_database_health() -> bool: """ Verificar conectividad con la base de datos. Returns: bool: True si la conexión es exitosa """ try: async with AsyncSessionLocal() as session: await session.execute("SELECT 1") return True except Exception: return False