DB_SCHEMA (по умолчанию dkb, валидация идентификатора) читают models/base.py (SCHEMA), db/db.py (search_path),
alembic/env.py и миграции 0001-0005 (SCHEMA и строковые FK f"{SCHEMA}.x.id" вместо литералов). В контуре -
OPENBAO__APP__DB_SCHEMA. Офлайн-SQL `alembic upgrade head --sql` при значении по умолчанию совпадает побайтно.
Тесты: валидация настройки, миграции и сессия приложения в схеме dkb_alt; .env.example/.env.test/README/CLAUDE.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAKRDNzXtRrwmWz9z6PZu3
36 lines
1.8 KiB
Python
36 lines
1.8 KiB
Python
from collections.abc import AsyncIterator
|
||
from contextlib import asynccontextmanager
|
||
|
||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||
|
||
# from fastapi_users.db import SQLAlchemyUserDatabase, SQLAlchemyBaseUserTableUUID
|
||
from src.core.config import settings
|
||
from src.models.base import SCHEMA
|
||
|
||
engine = create_async_engine(
|
||
settings.OPENBAO.DATABASE.DATABASE_URL, connect_args={"server_settings": {"search_path": SCHEMA}}
|
||
)
|
||
async_session_maker = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||
|
||
|
||
async def get_async_session() -> AsyncIterator[AsyncSession]:
|
||
"""Сессия запроса = одна транзакция: commit при успешном ответе, rollback при любом исключении (R-1, design #12).
|
||
|
||
В маршрутах объявляется только через `src.api.dependencies.db.SessionDep` (`scope="function"`): тогда commit
|
||
выполняется до отправки ответа, а все зависимости запроса получают одну и ту же сессию.
|
||
"""
|
||
async with async_session_maker() as session, session.begin():
|
||
yield session
|
||
|
||
|
||
@asynccontextmanager
|
||
async def session_transaction(
|
||
maker: async_sessionmaker[AsyncSession] | None = None,
|
||
) -> AsyncIterator[AsyncSession]:
|
||
"""Отдельная короткая транзакция вне сессии запроса (аудит входа): commit на выходе, rollback при исключении.
|
||
|
||
`maker` по умолчанию — `async_session_maker` приложения (читается при вызове: тесты его подменяют).
|
||
"""
|
||
async with (maker or async_session_maker)() as session, session.begin():
|
||
yield session
|