Files
auto-virtual-tryon/app/infra/db/session.py
2026-03-27 00:10:28 +08:00

66 lines
2.0 KiB
Python

"""Async database engine and session helpers."""
from collections.abc import AsyncGenerator
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine
from app.config.settings import get_settings
from app.infra.db.base import Base
_engine: AsyncEngine | None = None
_session_factory: async_sessionmaker[AsyncSession] | None = None
def get_async_engine() -> AsyncEngine:
"""Return the lazily created async SQLAlchemy engine."""
global _engine
if _engine is None:
_engine = create_async_engine(
get_settings().database_url,
future=True,
echo=False,
)
return _engine
def get_session_factory() -> async_sessionmaker[AsyncSession]:
"""Return the lazily created async session factory."""
global _session_factory
if _session_factory is None:
_session_factory = async_sessionmaker(get_async_engine(), expire_on_commit=False)
return _session_factory
async def get_db_session() -> AsyncGenerator[AsyncSession, None]:
"""Yield a database session for FastAPI dependencies."""
async with get_session_factory()() as session:
yield session
async def init_database() -> None:
"""Create database tables when running the MVP without migrations."""
from app.infra.db.models.asset import AssetORM
from app.infra.db.models.order import OrderORM
from app.infra.db.models.review_task import ReviewTaskORM
from app.infra.db.models.workflow_run import WorkflowRunORM
from app.infra.db.models.workflow_step import WorkflowStepORM
del AssetORM, OrderORM, ReviewTaskORM, WorkflowRunORM, WorkflowStepORM
async with get_async_engine().begin() as connection:
await connection.run_sync(Base.metadata.create_all)
async def dispose_database() -> None:
"""Dispose the active engine and clear cached session objects."""
global _engine, _session_factory
if _engine is not None:
await _engine.dispose()
_engine = None
_session_factory = None