Files
hunjing/backend/app/db/base.py
T
chenxin 28127949db ✨ feat: 数据库基线与通用 DTO(WP-01 第 3、4 步)
- 通用 DTO:Money(最小货币单位整数)、CursorPage 泛型、9 个平台 ID Annotated 类型(前缀+UUIDv7/v4 正则,与 openapi 契约对齐)
- db 基础:naming_convention Base(pk_/uq_/ix_/fk_,AGENTS 8.6)+ async engine + 事务作用域 session
- 首批 6 张表 typed mapping:user/personal_domain/session/service_account/audit_event/outbox_event;Session ID 为 CSPRNG opaque;审计与 Outbox 不可变
- Alembic async 迁移(含表注释);docker 起 hunjing-postgres 并 upgrade 验证:7 表、约束/索引命名全部符合约定
- 按 database-design skill 清单交叉检查:外键索引全覆盖(复合唯一最左前缀)、审计聚合时间线与 Outbox 投递扫描均为专用复合索引
- 集成测试 8 项(唯一约束、FK restrict/cascade、检查约束、同事务提交)连 PG 测试库运行;pytest 15 项、ruff、mypy strict 全绿
2026-09-10 10:00:17 +08:00

52 lines
1.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""数据库基础:命名约定、异步引擎与会话。
索引/约束命名按 AGENTS.md 8.6(pk_/uk_/idx_/fk_ + 表名);
主库统一 PostgreSQL(ADR-024),不提供 SQLite 档。
"""
from collections.abc import AsyncIterator
from sqlalchemy import MetaData
from sqlalchemy.ext.asyncio import (
AsyncEngine,
AsyncSession,
async_sessionmaker,
create_async_engine,
)
from sqlalchemy.orm import DeclarativeBase
from app.core.config import get_settings
naming_convention = {
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(constraint_name)s",
"fk": "fk_%(table_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
}
class Base(DeclarativeBase):
metadata = MetaData(naming_convention=naming_convention)
def create_engine() -> AsyncEngine:
return create_async_engine(get_settings().database_url, pool_pre_ping=True)
def create_session_factory(engine: AsyncEngine) -> async_sessionmaker[AsyncSession]:
return async_sessionmaker(engine, expire_on_commit=False)
async def session_scope(
factory: async_sessionmaker[AsyncSession],
) -> AsyncIterator[AsyncSession]:
"""事务作用域:成功提交、异常回滚(权威状态与 Outbox 同事务,契约第 4.4 节)。"""
async with factory() as session:
try:
yield session
await session.commit()
except Exception:
await session.rollback()
raise