59 lines
1.6 KiB
Python
59 lines
1.6 KiB
Python
"""MySQL 비동기 세션.
|
|
|
|
FastAPI 의존성으로 쓴다:
|
|
async def handler(session: AsyncSession = Depends(get_session)): ...
|
|
"""
|
|
from collections.abc import AsyncGenerator
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
|
from sqlalchemy.orm import DeclarativeBase
|
|
from sqlalchemy.pool import AsyncQueuePool
|
|
|
|
from settings import settings
|
|
|
|
POOL_SIZE = 10
|
|
MAX_OVERFLOW = 10
|
|
POOL_TIMEOUT = 30
|
|
POOL_RECYCLE = 3600 # 연결을 1시간마다 새로 맺는다
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
engine = create_async_engine(
|
|
settings.mysql_url,
|
|
pool_size=POOL_SIZE,
|
|
max_overflow=MAX_OVERFLOW,
|
|
poolclass=AsyncQueuePool,
|
|
pool_timeout=POOL_TIMEOUT,
|
|
pool_recycle=POOL_RECYCLE,
|
|
pool_pre_ping=True, # 끊긴 연결을 쓰기 전에 걸러낸다
|
|
pool_reset_on_return="rollback",
|
|
echo=False,
|
|
connect_args={
|
|
"connect_timeout": 10,
|
|
"read_timeout": 30,
|
|
"write_timeout": 30,
|
|
"charset": "utf8mb4",
|
|
"sql_mode": "STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE",
|
|
"init_command": "SET SESSION time_zone = '+00:00'",
|
|
},
|
|
)
|
|
|
|
session_factory = async_sessionmaker(bind=engine, class_=AsyncSession,
|
|
expire_on_commit=False, autoflush=False)
|
|
|
|
|
|
async def get_session() -> AsyncGenerator[AsyncSession, None]:
|
|
async with session_factory() as session:
|
|
try:
|
|
yield session
|
|
except Exception:
|
|
await session.rollback()
|
|
raise
|
|
|
|
|
|
async def close_engine() -> None:
|
|
await engine.dispose()
|