68 lines
2.2 KiB
Python
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
|