docs: 下阶段开发计划(架构 v2 落地 M6-M8)+ MySQL 迁移文档同步

- docs/DEV_PLAN_v2.md:基于 ARCHITECTURE_v2 与 M0-M5 现状的下一阶段计划
  (M-DB 迁移收尾 → M6 因子定义入库/复合因子/口径修复 → M7 Selection/Signal/
  Portfolio 引擎分层 → M8 Strategy 平台化/Web 做实/Agent 工具补齐;含本机 Redis
  127.0.0.1:6379 的接入触发点与执行顺序)
- ROADMAP.md:登记 M-DB 里程碑并指向 DEV_PLAN_v2
- USAGE.md / README.md:数据库描述由 SQLite 更新为 MySQL(config.yaml database.mysql)
This commit is contained in:
Simon
2026-09-08 23:58:51 +08:00
parent 6c2f198261
commit 0ffd574f30
4 changed files with 272 additions and 14 deletions
+23 -9
View File
@@ -64,7 +64,8 @@ cp .env.example .env
|---|---|---|
| `TUSHARE_TOKEN` | 同步数据时必填 | Tushare Pro token |
| `LLM_API_KEY` | 使用 Agent 时必填 | 大模型 API Key(URL/模型名在 config.yaml) |
| `DATABASE_URL` | 否 | 留空使用 SQLite `<项目根>/data/quant.db` |
| `DATABASE_URL` | 否 | 默认库 = `config.yaml → database.mysql`(MySQL `192.168.1.10/qlib`);设此项可覆盖(如切回 SQLite) |
| `MYSQL_PASSWORD` | 使用 MySQL 默认库时必填 | MySQL 密码(`config.yaml database.mysql.password_env` 引用;host/db/user 在 config.yaml) |
| `APP_SECRET_KEY` | 否 | 应用密钥(未接登录,可暂不改) |
> 约定:**密钥只放 `.env`**;URL、模型名等可配置项放 `config.yaml`。`.env` 已被 gitignore,严禁提交。
@@ -76,7 +77,12 @@ cp .env.example .env
```yaml
app: {name, version, debug, secret_key_env}
api: {prefix: "/api"}
database: {url_env: "DATABASE_URL", echo: false, migrations_dir: ...}
database:
url_env: "DATABASE_URL"
migrations_dir: ...
mysql: {enabled: true, host: "192.168.1.10", port: 3306,
db: "qlib", user: "qlib", password_env: "MYSQL_PASSWORD", charset: "utf8mb4"}
# URL 优先级:DATABASE_URL 环境变量 > database.mysql 组装 > sqlite:///./data/quant.db 兜底
data_source: {primary: "tushare", fallback: "sina", tushare_token_env: "TUSHARE_TOKEN"}
storage: {parquet_dir: "data/parquet", qlib_dir: "data/qlib", ...} # 相对项目根
agent:
@@ -94,12 +100,17 @@ agent:
```bash
cd backend
uv run alembic upgrade head # 建表(首次会自动建 data/quant.db)
uv run alembic upgrade head # 在 config 指定库上建表(默认 MySQL qlib;SQLite 兜底库为 data/quant.db)
# 开发中改 Model 后:
uv run alembic revision --autogenerate -m "desc"
uv run alembic upgrade head
# 对指定库执行(不随默认配置):
DATABASE_URL='mysql+pymysql://user:pass@host/db' uv run alembic upgrade head
```
> 2026-09 已把数据从 SQLite(`data/quant.db`)全量迁移至 MySQL(`192.168.1.10:3306/qlib`),
> 迁移工具与校验见 `scripts/migrate_sqlite_to_mysql.py`(`--verify-only` 可复查一致性)。
---
## 4. 数据同步与导出
@@ -320,9 +331,12 @@ pnpm run build
- **前端连不上后端 / NetworkError**:前端默认经 Next **同源代理**访问 `/api/*`
(next.config.ts rewrites → `127.0.0.1:8000`,可用 `BACKEND_API_URL` 覆盖),
任意 IP 访问 `:3000` 都不需要 CORS 或硬编码后端地址;后端 CORS 开发期为 `*`。
若 API 返回 500 且日志出现 `database is locked`,多半是正在跑全市场数据同步
(长写事务),同步结束后自动恢复(引擎已加 busy_timeout 等待)。
- **数据库被改动想重置**:删除 `data/quant.db` 后 `uv run alembic upgrade head` 重建
表结构(行情需重新同步)。
- **想切换 MySQL**:`.env` 设 `DATABASE_URL=mysql+pymysql://user:pass@host/db`,
业务层无需改动(Repository 已隔离)。
若使用 SQLite 兜底库且日志出现 `database is locked`,多半是正在跑全市场数据
同步(长写事务),同步结束后自动恢复(SQLite 连接已加 busy_timeout);
默认 MySQL 库无此问题。
- **数据库被改动想重置**:默认 MySQL(qlib@192.168.1.10)时在远端重建后
`uv run alembic upgrade head`(行情需重新同步或从备份恢复);若切回 SQLite 兜底库则删除
`data/quant.db` 后重建。
- **默认库已是 MySQL**(config.yaml `database.mysql`,密码在 `.env` 的 `MYSQL_PASSWORD`);
**想临时切回 SQLite**:`.env` 设 `DATABASE_URL=sqlite:///./data/quant.db`。
业务层均无需改动(Repository / SQLAlchemy 已隔离方言差异)。