feat(db): SQLite 全量迁移至 MySQL(config.yaml 配置化 + 迁移脚本 + 一致性校验)

- config.yaml database.mysql:host/port/db/user/charset 明文可提交;密码经 password_env
  引用 .env 的 MYSQL_PASSWORD(AGENT.md §33 密钥不进 git)
- config.py _build_mysql_url:URL 优先级 DATABASE_URL env > database.mysql 段 > sqlite 兜底
- pyproject 引入 pymysql>=1.1
- tests/conftest.py 强制每进程 /tmp SQLite(测试绝不触 MySQL 开发库);test_config 覆盖
  mysql 组装/密码可选/sqlite 兜底分支
- scripts/migrate_sqlite_to_mysql.py:sqlite→mysql 一次性迁移工具(keyset 分页 + chunk
  多值 INSERT + 攒批 commit + 幂等续传 + 低配 MySQL 节流 --throttle-sec + --verify-only
  行数与抽样一致性校验);已用于 data/quant.db 约 1605 万行迁移并经校验一致
This commit is contained in:
Simon
2026-09-08 23:58:48 +08:00
parent a3fabf9ae9
commit 6c2f198261
8 changed files with 409 additions and 20 deletions
+15 -1
View File
@@ -17,11 +17,25 @@ api:
prefix: "/api"
database:
# 留空 → 默认 sqlite:///./data/quant.db(相对路径自动解析到项目根 data/)
# 数据库 URL 选择优先级:
# 1) 环境变量 database.url_env(如 DATABASE_URL,可在 .env 覆盖)
# 2) database.mysql(enabled: true 时由 host/port/db/user 组装 mysql+pymysql URL)
# 3) 兜底 sqlite:///./data/quant.db(相对路径自动解析到项目根 data/)
url_env: "DATABASE_URL"
echo: false
# Alembic 迁移脚本目录(相对 backend/)
migrations_dir: "app/infrastructure/persistence/migrations"
# ---- MySQL(当前默认库;2026-09 由 SQLite data/quant.db 全量迁移而来)----
# host/port/db/user 明文可提交;密码经 password_env 引用 .env 变量
# (AGENT.md §33:密钥只放根目录 .env,本文件不写明文密码)。
mysql:
enabled: true
host: "192.168.1.10"
port: 3306
db: "qlib"
user: "qlib"
password_env: "MYSQL_PASSWORD"
charset: "utf8mb4"
data_source:
primary: "tushare"