"""MySQL 会话(懒):首次访问才创建 AsyncEngine + 连接池,不随应用启动初始化。 引擎/会话工厂都是函数式访问,第一次调用时建出单例;dispose 清理已建对象。 """ from sqlalchemy import text from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine from config.settings import settings _engine = None _sessionmaker = None def get_engine(): global _engine if _engine is None: _engine = create_async_engine( settings.mysql.url, pool_size=settings.mysql.pool_size, max_overflow=settings.mysql.max_overflow, pool_recycle=settings.mysql.pool_recycle, pool_pre_ping=True, # 取/还连接时探测,自动剔除死连接 pool_timeout=settings.mysql.pool_timeout, connect_args={"connect_timeout": settings.mysql.connect_timeout}, ) return _engine def get_session_factory(): global _sessionmaker if _sessionmaker is None: _sessionmaker = async_sessionmaker(bind=get_engine(), expire_on_commit=False) return _sessionmaker async def init_db() -> None: """手动预热入口(registry.init_db 逐库调用;不随应用启动自动执行)。""" get_engine() async def dispose() -> None: global _engine, _sessionmaker if _engine is not None: await _engine.dispose() _engine = None _sessionmaker = None async def check_health() -> None: async with get_engine().connect() as conn: await conn.execute(text("SELECT 1"))