from sqlalchemy import create_engine, event from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from sqlalchemy.pool import QueuePool from .settings import settings from .logging_config import get_logger logger = get_logger(__name__) # Database configuration using settings DATABASE_URL = settings.database_url # Enhanced engine configuration for enterprise use engine = create_engine( DATABASE_URL, poolclass=QueuePool, pool_pre_ping=True, # Verify connections before using pool_recycle=3600, # Recycle connections after 1 hour pool_size=10, # Number of connections to maintain max_overflow=20, # Additional connections beyond pool_size echo=settings.is_development, # Log SQL queries in development future=True, # Use SQLAlchemy 2.0 style connect_args={ "charset": "utf8mb4", "connect_timeout": 10 } ) # Event listeners for connection pool monitoring @event.listens_for(engine, "connect") def set_sqlite_pragma(dbapi_conn, connection_record): """Set connection-level settings""" logger.debug("New database connection established") @event.listens_for(engine, "checkout") def receive_checkout(dbapi_conn, connection_record, connection_proxy): """Log connection checkout""" logger.debug("Connection checked out from pool") @event.listens_for(engine, "checkin") def receive_checkin(dbapi_conn, connection_record): """Log connection checkin""" logger.debug("Connection returned to pool") SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() # Dependency to get DB session def get_db(): """ Dependency for getting database session. Automatically handles session lifecycle. """ db = SessionLocal() try: yield db except Exception: db.rollback() raise finally: db.close()