from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession from sqlalchemy.orm import sessionmaker from config import settings from utils.logger import session_logger import asyncio import urllib.parse class DatabaseManager: _instance = None _lock = asyncio.Lock() def __init__(self): self.engine = None self.async_session = None self._initialized = False @classmethod async def get_instance(cls): async with cls._lock: if cls._instance is None: cls._instance = DatabaseManager() if not cls._instance._initialized: await cls._instance.initialize() return cls._instance async def initialize(self): if self._initialized: return try: encoded_password = urllib.parse.quote_plus(settings.db_password) connection_string = f"mysql+aiomysql://{settings.db_user}:{encoded_password}@{settings.db_host}:{settings.db_port}/{settings.db_name}?charset=utf8mb4" self.engine = create_async_engine( connection_string, echo=settings.db_echo, pool_pre_ping=True, pool_recycle=3600, ) self.async_session = sessionmaker( self.engine, expire_on_commit=False, class_=AsyncSession ) self._initialized = True session_logger.info("system", "database", f"数据库连接初始化成功: {settings.db_host}:{settings.db_port}/{settings.db_name}") except Exception as e: session_logger.error("system", "database", f"数据库连接初始化失败: {str(e)}") raise async def get_session(self): """获取数据库会话""" if not self._initialized: await self.initialize() return self.async_session() async def close(self): """关闭数据库连接""" if self.engine: await self.engine.dispose() self._initialized = False session_logger.info("system", "database", "数据库连接已关闭") db_manager = None async def get_db_manager(): global db_manager if db_manager is None: db_manager = await DatabaseManager.get_instance() return db_manager