feat(backend): 搭建 FastAPI 分层骨架 — 配置加载 / 健康检查 / SQLAlchemy+Alembic 就位

- uv 工程(Python 3.12,pyproject + uv.lock,dev: pytest/ruff)
- 分层包结构:api / application / domain / infrastructure / quant(qlib_adapter) / agent / core
- app.core.config:加载根 config.yaml + .env,sqlite 相对路径解析到项目根 data/
- SQLAlchemy Base + Session 工厂(Infrastructure 层,业务走 Repository)
- Alembic 迁移环境就位(env.py 复用应用配置,render_as_batch 兼容 SQLite)
- GET /api/health + pytest 冒烟 6 项通过 / ruff clean / uvicorn 启动验证
This commit is contained in:
Simon
2026-09-06 16:09:10 +08:00
parent 8eb3b4ac2a
commit 2a52ee5e83
32 changed files with 1443 additions and 0 deletions
@@ -0,0 +1 @@
"""SQLAlchemy 2.x 基础设施(当前 SQLite,未来 MySQL 同实现,仅 URL 不同)。"""
@@ -0,0 +1,12 @@
"""所有 ORM Model 的声明式基类。
新表 Model 必须继承本类;改动后通过 Alembic autogenerate 生成迁移。
"""
from __future__ import annotations
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
"""声明式 ORM 基类(SQLAlchemy 2.x 风格)。"""
@@ -0,0 +1,5 @@
"""ORM 模型目录。
新增表流程(AGENT.md §12):Model → Alembic Migration → Test。
模型统一继承 infra.persistence.sqlalchemy.base.Base。
"""
@@ -0,0 +1,5 @@
"""Repository 的 SQLAlchemy 实现。
职责:把 domain Repository Protocol 翻译成 SQLAlchemy 查询。
业务 Service 只依赖 Protocol,不 import 本目录实现(由依赖注入装配)。
"""
@@ -0,0 +1,38 @@
"""SQLAlchemy engine / Session 工厂与 FastAPI 依赖。
注意:本文件属于 Infrastructure 层,是唯一允许出现 engine 创建的地方之一。
业务 Service / Domain 禁止直接使用 Session —— 一律通过 Repository。
"""
from __future__ import annotations
from collections.abc import Generator
from sqlalchemy import create_engine
from sqlalchemy.orm import Session, sessionmaker
from app.core.config import get_settings
_settings = get_settings()
engine = create_engine(
_settings.database_url,
echo=_settings.sqlalchemy_echo,
future=True,
)
SessionLocal = sessionmaker(
bind=engine,
autoflush=False,
expire_on_commit=False,
class_=Session,
)
def get_session() -> Generator[Session, None, None]:
"""FastAPI 依赖:每个请求一个 Session,请求结束自动关闭。
供 Repository 实现内部使用;业务层通过 Repository 间接访问。
"""
with SessionLocal() as session:
yield session