Files
Profeto/experts/review-engineer/reports/db-pipeline-review-2026-09-16.md
T
shangfangjian 5676198392 chore: 添加专家工作区目录结构
为代码审查、数据工程、后端架构、安全工程四个角色
建立专属工作区,用于持久化审查报告、设计文档和知识积累
2026-09-16 13:34:42 +08:00

3.4 KiB

Profeto 数据库与数据管线审查报告

审查日期: 2026-09-16 审查范围: 6 张表 ORM、6 个迁移文件、3 个采集器、上下文构建器、API 路由、连接池配置 结论: 发现 6 个 P1 + 5 个 P2 问题(无 P0)


P1 级问题(6 个)

P1-1: context_builder.py session 管理

  • 文件: src/llm/context_builder.py
  • 问题: 每个切片函数独立创建 session。回测 20 场并发需 120 个连接,池仅 15 个 → 耗尽阻塞
  • 修复: build_context 创建共享 session 并传给所有切片函数,切片函数新增可选 db 参数

P1-2: bzzoiro.py 内存预加载

  • 文件: src/data/bzzoiro.py
  • 问题: 预加载联赛全部比赛到内存(select(Match).where(Match.league_id == league.id)),多赛季采集时内存溢出
  • 修复: 改为按 raw_events 日期范围 ±30 天按需加载

P1-3: understat.py N+1 查询

  • 文件: src/data/understat.py
  • 问题: 逐条查询比赛(每场 3 次 DB 往返),单赛季 380 次 = 1140 次往返
  • 修复: 批量查询球队(1 次) + 批量查询比赛(1 次) + 内存匹配

P1-4: injuries.py 幂等检查竞态条件

  • 文件: src/data/injuries.py
  • 问题: check-then-insert 模式,并发采集触发 IntegrityError 导致整批回滚
  • 修复: 批量幂等检查 + 分批 flush + 失败回退逐条插入

P1-5: predict.py 同步 Lock 用于 async

  • 文件: src/llm/predict.py
  • 问题: threading.Lock 用于 async 函数,阻塞事件循环
  • 修复: 删除 Lock,dict 操作在 CPython GIL 下原子

P1-6: models.py 缺唯一约束

  • 文件: src/db/models.py
  • 问题: 缺 (match_id, provider, model) 唯一约束,重复预测导致统计偏差
  • 修复: 添加 UniqueConstraint + 迁移文件

P2 级问题(5 个)

P2-1: unit_of_work 类型注解错误

  • 文件: src/db/unit_of_work.py
  • 问题: AsyncIterator[AsyncSessionLocal] 应为 AsyncIterator[AsyncSession]

P2-2: normalize.py 日期解析静默丢弃

  • 文件: src/data/normalize.py
  • 问题: _parse_date 失败返回 None,数据丢失无感知
  • 修复: 解析失败时 logger.warning 记录原始值

P2-3: repositories.py func.date() 索引失效

  • 文件: src/db/repositories.py
  • 问题: func.date(Match.match_date) 致索引失效,全表扫描
  • 修复: 改用 Match.match_date_date 等值匹配

P2-4: 迁移 0005 幽灵列

  • 文件: alembic/versions/0005
  • 问题: cutoff_at 列被注释掉未删除,autogenerate 噪声
  • 状态: 已在 0006 迁移中修复

P2-5: 迁移 0003 约束命名不一致

  • 文件: alembic/versions/0003_injuries.py
  • 问题: UniqueConstraint vs ORM 的 Index(unique=True) 不一致
  • 修复: 新迁移 0007 将 UniqueConstraint 替换为唯一索引

值得肯定的设计

  • 索引/约束设计合理(唯一约束防重、CHECK 约束、复合索引)
  • 数据血缘追踪(source / retrieved_at / available_at)完善
  • 采集管线有重试、限速、防回测泄漏
  • get_db / get_db_read 读写分离
  • 迁移规范,有 downgrade

修复验证

  • 全部文件语法检查通过
  • 11 个文件修改 + 2 个新迁移
  • MR #3 已提交: #3
  • 合并后运行 alembic upgrade head
  • 20 场并发回测压测验证连接池