130 lines
5.8 KiB
Markdown
130 lines
5.8 KiB
Markdown
# Tushare PostgreSQL 同步实施计划
|
|
|
|
## 实施原则
|
|
|
|
- 按以下顺序增量交付,每一步先写对应行为测试,再补最小实现。
|
|
- 不修改旧项目;不导入其带有最新市值回填的历史 CSV。
|
|
- 不在本任务中实现选股策略、HTTP 管理接口或宿主机 crontab 写入。
|
|
- schema、CSV 契约和批次状态一旦被后续步骤使用,变更时必须同步更新迁移、测试和设计文档。
|
|
|
|
## 1. 依赖、配置与迁移骨架
|
|
|
|
- 在 `zhixing-server/pyproject.toml` 增加 Tushare、Psycopg 3、SQLAlchemy 和 Alembic 依赖并更新 `uv.lock`。
|
|
- 扩展 `bootstrap.config.Settings`:数据库 URL、Tushare token、CSV 根目录、覆盖率阈值、并发/限流/重试参数;保持 `ZHIXING_` 前缀且不暴露秘密。
|
|
- 初始化 Alembic 配置和 metadata,创建股票、日线、每日指标、同步 batch/item 表及唯一约束、索引。
|
|
- 增加 migration 集成测试,验证空库 upgrade 到 head、唯一约束和必要索引。
|
|
|
|
验证:
|
|
|
|
```bash
|
|
cd zhixing-server
|
|
uv sync
|
|
uv run alembic upgrade head
|
|
uv run pytest tests/integration/test_market_data_migrations.py
|
|
```
|
|
|
|
回滚点:本阶段只建立 schema;若迁移失败,修正 migration 后重建测试库,不对生产卷执行手工 DDL。
|
|
|
|
## 2. 领域模型、规范化与端口
|
|
|
|
- 创建 `modules/market_data` 四层目录和 bounded-context README。
|
|
- 定义 `ts_code`、目标交易日、六年窗口、bar、daily basic、batch/item 状态和值对象。
|
|
- 定义 Tushare 来源、快照存储、市场数据仓储、批次仓储和同步锁端口。
|
|
- 实现固定列、日期、小数、空值规范化,完整重叠区间 SHA-256 计算和变化分类。
|
|
- 先用纯领域测试覆盖:初次同步、仅新增日期、历史值变化、重叠区间缺行、输入顺序变化、空值/小数稳定性和窗口边界。
|
|
|
|
验证:
|
|
|
|
```bash
|
|
cd zhixing-server
|
|
uv run pytest tests/unit/market_data/test_fingerprint.py tests/unit/market_data/test_window.py
|
|
```
|
|
|
|
## 3. Tushare 与 CSV 适配器
|
|
|
|
- 封装 `stock_basic`、`trade_cal`、`pro_bar(adj="qfq")` 和 `daily_basic(trade_date=...)`,把 DataFrame 转为领域记录。
|
|
- 实现当前沪深非 ST 股票池过滤、请求退避/抖动和可配置并发限制。
|
|
- 实现 bar 按股票、daily basic 按日期、stock basic 当前版的临时 CSV 写入、校验、指纹读取、原子晋升和过期文件清理。
|
|
- 通过 fake Tushare 客户端与临时目录测试,不让普通单元测试访问真实网络。
|
|
|
|
验证:
|
|
|
|
```bash
|
|
cd zhixing-server
|
|
uv run pytest tests/unit/market_data/test_tushare_adapter.py tests/unit/market_data/test_csv_snapshot_store.py
|
|
```
|
|
|
|
回滚点:正式 CSV 只在数据库提交后晋升;适配器测试必须证明异常路径保留旧文件。
|
|
|
|
## 4. PostgreSQL 批量仓储
|
|
|
|
- 使用 Psycopg 连接/事务实现股票主数据、bar、daily basic、batch/item 和 advisory lock 适配器。
|
|
- 对 bar 和 daily basic 使用临时 staging + `COPY` + 集合式 upsert;通过 `IS DISTINCT FROM` 避免无意义 update。
|
|
- 实现 insert-only、新窗口完整修复、窗口内缺失删除和六年前数据清理。
|
|
- 集成测试覆盖幂等、更新计数、单股票回滚、日期事务回滚、并发锁以及数据库最终与快照一致。
|
|
|
|
验证:
|
|
|
|
```bash
|
|
cd zhixing-server
|
|
uv run pytest tests/integration/test_market_data_repository.py
|
|
```
|
|
|
|
## 5. 同步用例与失败重试
|
|
|
|
- 实现 `SyncMarketData.execute()`:解析目标交易日、刷新股票池、创建批次、回补/更新 daily basic、逐股票同步 bar、收敛状态和覆盖率。
|
|
- 初始化模式只回补缺失开市日;日常模式只获取目标日 daily basic,但每股始终拉六年 qfq。
|
|
- 实现父 batch 的失败股票和失败指标日期重试;成功项不回滚、不重复抓取。
|
|
- 用 fake 端口编排测试覆盖 `success`、`partial_success`、`failed`、99% 阈值、旧数据不得计入有效集合、CSV 发布失败和重试恢复。
|
|
|
|
验证:
|
|
|
|
```bash
|
|
cd zhixing-server
|
|
uv run pytest tests/unit/market_data/test_sync_market_data.py
|
|
```
|
|
|
|
## 6. CLI、Compose 与运维文档
|
|
|
|
- 增加 console script/CLI,支持普通同步、显式目标日期、初始化和按 batch 重试;输出批次摘要并返回稳定退出码。
|
|
- 在 dev/prod Compose 中增加 PostgreSQL、CSV 持久卷、`migrate` 和 `market-sync` profile Job,复用后端镜像和统一环境配置。
|
|
- 更新 `.env.example` 与部署文档,提供 migration、手工运行、失败重试和宿主机 cron 示例;不自动写入 crontab。
|
|
- 验证正常 `up` 不启动 Job,显式 `run --rm` 能连接数据库与 CSV 卷。
|
|
|
|
验证:
|
|
|
|
```bash
|
|
docker compose -f docker-compose.prod.yml config
|
|
docker compose -f docker-compose.dev.yml config
|
|
docker compose -f docker-compose.prod.yml --profile jobs config
|
|
```
|
|
|
|
## 7. 全链路验收与质量门禁
|
|
|
|
- 使用受控 fixture 或测试 Tushare 适配器完成空库初始化、无变化重跑、仅新增日期、历史 qfq 修订、单股票失败和定向重试场景。
|
|
- 核对 batch/item 计数、覆盖率、数据库内容、正式 CSV、六年清理和秘密脱敏。
|
|
- 若运行真实 Tushare smoke test,必须由显式环境开关启用,限制少量股票且不把 token 写入测试输出。
|
|
- 运行后端和根目录质量门禁;修复所有 Ruff、Pyright、pytest 与 Compose config 问题。
|
|
|
|
验证:
|
|
|
|
```bash
|
|
cd zhixing-server
|
|
uv run ruff format --check .
|
|
uv run ruff check .
|
|
uv run pyright
|
|
uv run pytest
|
|
cd ..
|
|
./dev.sh check
|
|
./dev.sh test
|
|
git diff --check
|
|
```
|
|
|
|
## 开始实施前检查
|
|
|
|
- [ ] 用户已在最终规划摘要之后明确批准实施。
|
|
- [ ] `prd.md`、`design.md`、`implement.md` 内容一致且无阻塞问题。
|
|
- [ ] `implement.jsonl` 与 `check.jsonl` 各自至少包含一条真实规格/研究上下文。
|
|
- [ ] `task.py validate tushare-postgres-sync` 通过。
|
|
- [ ] 当前工作区已有改动已识别,实施不覆盖用户或其他任务的文件。
|