Files
sakhteman/core/service/mysql_db.py
T
2026-02-17 22:37:43 +03:30

68 lines
2.2 KiB
Python

"""
اتصال 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