""" اتصال MySQL فقط-خواندنی (read-only). از پول کانکشن استفاده می‌کند و در هر کانکشن SESSION را به حالت فقط-خواندنی تنظیم می‌کند. """ from contextlib import asynccontextmanager from typing import Optional import aiomysql from core.utils.mysql import get_mysql_config _pool: Optional[aiomysql.Pool] = None _pool_connection_name: Optional[str] = None async def get_mysql_pool(connection_name: str = None) -> aiomysql.Pool: """پول کانکشن MySQL را برمی‌گرداند؛ در اولین فراخوانی ساخته می‌شود.""" global _pool, _pool_connection_name name = connection_name or "mysql" if _pool is None or _pool_connection_name != name: if _pool is not None: _pool.close() await _pool.wait_closed() cfg = get_mysql_config(name) _pool = await aiomysql.create_pool( host=cfg["host"], port=cfg["port"], user=cfg["user"], password=cfg["password"], db=cfg["db"], charset="utf8mb4", autocommit=True, minsize=1, maxsize=10, ) _pool_connection_name = name return _pool @asynccontextmanager async def get_mysql_connection(connection_name: str = None): """ کانکشن فقط-خواندنی از پول می‌گیرد. در ابتدا SESSION را به حالت فقط-خواندنی تنظیم می‌کند (برای اطمینان بیشتر). استفاده: async with get_mysql_connection() as conn: async with conn.cursor(aiomysql.DictCursor) as cur: await cur.execute("SELECT * FROM t LIMIT 10") rows = await cur.fetchall() """ pool = await get_mysql_pool(connection_name) conn = await pool.acquire() try: async with conn.cursor() as cur: await cur.execute("SET SESSION TRANSACTION READ ONLY") yield conn finally: pool.release(conn) async def close_mysql_pool(): """بستن پول (مثلاً در shutdown اپ).""" global _pool if _pool is not None: _pool.close() await _pool.wait_closed() _pool = None