# Database.py """ Configuracion de la base de datos para XMA en PostgresSQL """ """ Configuracion de la base de datos para XMA en PostgresSQL """ import os from sqlalchemy import create_engine, event, text from sqlalchemy.orm import sessionmaker, Session from sqlalchemy.pool import QueuePool from sqlalchemy.ext.declarative import declarative_base from typing import Generator import logging logger = logging.getLogger(__name__) # URL DATABASE_URL = os.getenv( "DATABASE_URL", "postgresql+psycopg2://postgres:postgres@localhost:5432/postgres", ) # Configuracion de las conexiones POOL_SIZE = int(os.getenv("DB_POOL_SIZE", "20")) MAX_OVERFLOW = int(os.getenv("DB_MAX_OVERFLOW", "10")) POOL_TIMEOUT = int(os.getenv("DB_POOL_TIMEOUT", "30")) POOL_RECYCLE = int(os.getenv("DB_POOL_RECYCKE", "3600")) ECHO = os.getenv("DB_ECHO", "False").lower() == "true" # Create Engine engine = create_engine( DATABASE_URL, poolclass=QueuePool, pool_size=POOL_SIZE, max_overflow=MAX_OVERFLOW, pool_timeout=POOL_TIMEOUT, pool_recycle=POOL_RECYCLE, pool_pre_ping=True, echo=ECHO, connect_args={ "connect_timeout": 10, "keepalives": 1, "keepalives_idle": 30, "keepalives_interval": 10, "keepalives_count": 5 } ) Base = declarative_base() def test_connection(): """Prueba de conexion a la bd""" try: with engine.connect() as conn: result = conn.execute(text("SELECT 1")) result.fetchone() logger.info("Conexion a postgres establecida") return True except Exception as e: logger.error(f"Error al conectar a postgres: {e}") return False # Session Local sessionLocal = sessionmaker( autocommit=False, autoflush=False, bind=engine, expire_on_commit=False ) def get_db() -> Generator[Session, None, None]: """Dependencia para FastAPI""" db = sessionLocal() try: yield db except Exception as e: logger.error(f"Error en session de base de datos: {e}") db.rollback() raise finally: db.close() @event.listens_for(engine, "connect") def receive_connect(dbapi_connection, connection_record): logger.debug("Nueva conexión a PostgreSQL establecida") @event.listens_for(engine, "checkout") def receive_checkout(dbapi_connection, connection_record, connection_proxy): logger.debug("Conexión tomada del pool") @event.listens_for(engine, "checkin") def receive_checkin(dbapi_connection, connection_record): logger.debug("Conexión devuelta al pool") def dispose_engine(): engine.dispose() logger.info("Pool de conexiones cerrado")