Files
monlet/server/monlet_server/db.py
2026-05-28 14:19:27 +04:00

54 lines
1.4 KiB
Python

from collections.abc import AsyncIterator
from sqlalchemy.ext.asyncio import (
AsyncEngine,
AsyncSession,
async_sessionmaker,
create_async_engine,
)
from .settings import get_settings
_engine: AsyncEngine | None = None
_sessionmaker: async_sessionmaker[AsyncSession] | None = None
def get_engine() -> AsyncEngine:
global _engine, _sessionmaker
if _engine is None:
s = get_settings()
# PH-016: explicit pool sizing. pool_pre_ping protects against stale
# connections after PG restarts; pool_recycle bounds connection age.
_engine = create_async_engine(
s.database_url,
pool_pre_ping=True,
pool_size=s.db_pool_size,
max_overflow=s.db_max_overflow,
pool_timeout=s.db_pool_timeout_sec,
pool_recycle=s.db_pool_recycle_sec,
future=True,
)
_sessionmaker = async_sessionmaker(_engine, expire_on_commit=False)
return _engine
def get_sessionmaker() -> async_sessionmaker[AsyncSession]:
if _sessionmaker is None:
get_engine()
assert _sessionmaker is not None
return _sessionmaker
async def dispose_engine() -> None:
global _engine, _sessionmaker
if _engine is not None:
await _engine.dispose()
_engine = None
_sessionmaker = None
async def get_session() -> AsyncIterator[AsyncSession]:
sm = get_sessionmaker()
async with sm() as session:
yield session