64 lines
2.0 KiB
Python
64 lines
2.0 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 AsyncAdaptedQueuePool
|
|
|
|
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=AsyncAdaptedQueuePool,
|
|
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, # asyncmy에는 write_timeout이 없다
|
|
"charset": "utf8mb4",
|
|
# sql_mode는 asyncmy가 따옴표 없이 끼워 넣어 문법 오류가 나므로 여기서 같이 건다
|
|
"init_command": ("SET SESSION time_zone = '+00:00', "
|
|
"sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE'"),
|
|
},
|
|
)
|
|
|
|
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 create_missing_tables() -> None:
|
|
"""없는 테이블만 만든다. 컬럼이 바뀐 기존 테이블은 건드리지 않는다"""
|
|
async with engine.begin() as connection:
|
|
await connection.run_sync(Base.metadata.create_all)
|
|
|
|
|
|
async def close_engine() -> None:
|
|
await engine.dispose()
|