在准备环境前提交次全部更改。

This commit is contained in:
Neo
2026-02-19 08:35:13 +08:00
parent ded6dfb9d8
commit 4eac07da47
1387 changed files with 6107191 additions and 33002 deletions

View File

@@ -0,0 +1 @@
{"generationMode": "requirements-first"}

View File

@@ -0,0 +1,374 @@
# 设计文档ETL 管道全流程调试与 Debug
## 概述
本设计覆盖 `apps/etl/pipelines/feiqiu/` 下 ETL 管道的全流程调试,采用五阶段策略:
1. **分层单元调试**逐层ODS → DWD → DWS → INDEX使用 FakeDB/FakeAPI 和真实数据库验证任务逻辑
2. **全量数据刷新**:执行 2026-01-01 至 2026-02-16 的 `api_full` Flow内嵌性能计时边执行边 Debug发现问题即修复并重试
3. **黑盒数据校验**:从 API 源数据出发,逐层对比各 Schema 各表的记录数、金额汇总、可疑值检测和抽样逐字段比对
4. **架构优化分析**:分析 ETL 整体结构,在保证稳定和正确的基础上提出精简架构的建议,生成架构报告
5. **报告生成**:基于全量刷新阶段采集的计时数据生成性能分析报告,汇总所有调试结果生成 Debug 报告
性能计时从全量刷新阶段开始就嵌入采集(每任务/每层/API 调用耗时),报告阶段仅做分析和输出,不再单独重跑流程采集数据。
调试使用 `.env` 中配置的真实 API 和数据库连接test_etl_feiqiu所有发现的问题和修复记录在结构化 Debug 报告中。性能计时在全量刷新阶段实时采集,报告阶段读取中间数据做分析输出。
## 架构
### 调试流程架构
```mermaid
flowchart TD
A[阶段1: 分层单元调试] --> B[阶段2: 全量数据刷新<br/>内嵌性能计时]
B --> C[阶段3: 黑盒数据校验]
C --> D[阶段4: 架构优化分析]
D --> E[阶段5: 报告生成<br/>含性能分析]
subgraph 阶段1 [分层单元调试]
A1[ODS 层: API抓取 → 表写入] --> A2[DWD 层: ODS → DWD 清洗装载]
A2 --> A3[DWS 层: DWD → DWS 汇总]
A3 --> A4[INDEX 层: 指数算法计算]
A4 --> A5[编排层: PipelineRunner + TaskExecutor]
A5 --> A6[CLI 入口: 参数解析 + 模式切换]
A6 --> A7[配置体系: AppConfig 加载合并]
end
subgraph 阶段2 [全量数据刷新 - 内嵌计时 + 边执行边Debug]
B1[api_full Flow 执行<br/>每任务/每层计时] --> B2{发现Bug?}
B2 -->|是| B3[修复Bug]
B3 --> B4[重试失败的层/任务]
B4 --> B2
B2 -->|否| B5[increment_verify 校验]
B5 --> B6[自动补齐缺失数据]
B6 --> B7[输出计时 JSON 中间文件]
end
subgraph 阶段3 [黑盒数据校验]
C1[API → ODS 记录数对比] --> C2[ODS → DWD 记录数+金额对比]
C2 --> C3[DWD → DWS 聚合一致性]
C3 --> C4[可疑值检测: 边缘值/空值/重复]
C4 --> C5[抽样100条逐字段比对]
end
subgraph 阶段4 [架构优化分析]
D1[代码结构分析] --> D2[冗余识别]
D2 --> D3[精简建议]
end
subgraph 阶段5 [报告生成 - 含性能分析]
E1[读取计时 JSON] --> E2[瓶颈识别 + 优化建议]
E2 --> E3[汇总 Debug 报告]
end
```
### 现有系统架构
```mermaid
flowchart LR
CLI[cli/main.py] --> PR[PipelineRunner]
CLI --> TE[TaskExecutor]
PR --> TE
TE --> TR[TaskRegistry<br/>52个任务]
TE --> CM[CursorManager]
TE --> RT[RunTracker]
TR --> ODS[ODS 任务<br/>BaseOdsTask × 23]
TR --> DWD[DWD 任务<br/>DwdLoadTask]
TR --> DWS[DWS 任务<br/>BaseDwsTask × 15]
TR --> IDX[INDEX 任务 × 4]
TR --> UTL[工具类任务 × 7]
ODS --> API[APIClient<br/>上游 SaaS]
ODS --> DB[(PostgreSQL<br/>ods.*)]
DWD --> DB
DWS --> DB
IDX --> DB
QC[IntegrityChecker] --> API
QC --> DB
```
## 组件与接口
### 调试脚本组件
调试通过一组 Python 脚本实现,放置在 `apps/etl/pipelines/feiqiu/scripts/debug/` 目录下:
| 脚本 | 职责 | 对应需求 |
|------|------|----------|
| `debug_ods.py` | ODS 层逐任务调试:连接真实 API 和 DB执行单个 ODS 任务并验证写入结果 | 需求 1, 9 |
| `debug_dwd.py` | DWD 层调试:执行 DWD_LOAD_FROM_ODS 并验证 TABLE_MAP 中每对映射的记录数 | 需求 2, 9 |
| `debug_dws.py` | DWS 层调试:逐个执行 DWS 任务并验证汇总结果 | 需求 3, 9 |
| `debug_index.py` | INDEX 层调试:执行 4 个指数任务并验证计算结果 | 需求 4, 9 |
| `debug_orchestration.py` | 编排层调试:验证 PipelineRunner 和 TaskExecutor 的流程控制 | 需求 5 |
| `run_full_refresh.py` | 全量刷新:执行 2026-01-01 ~ 2026-02-16 的 api_full内嵌性能计时边执行边 Debug发现问题即修复重试输出计时 JSON | 需求 10, 13 |
| `debug_blackbox.py` | 黑盒校验:从 API 源数据逐层对比各表数据完整性 + 可疑值检测 + 抽样逐字段比对 | 需求 12 |
| `analyze_performance.py` | 性能分析:读取全量刷新采集的计时 JSON统计耗时识别瓶颈生成性能优化报告 | 需求 13 |
| `analyze_architecture.py` | 架构分析:分析代码结构,识别冗余和可精简点,生成架构优化报告 | 需求 14 |
| `generate_report.py` | 报告生成:汇总所有调试结果生成 Markdown 报告 | 需求 11 |
### 关键接口
```python
# 调试脚本的统一入口接口
class DebugResult:
"""单个调试步骤的结果"""
layer: str # "ODS" / "DWD" / "DWS" / "INDEX" / "ORCHESTRATION"
task_code: str # 任务代码
status: str # "PASS" / "FAIL" / "WARN" / "ERROR"
message: str # 结果描述
details: dict # 详细信息(记录数、错误堆栈等)
fix_applied: str | None # 已应用的修复措施
class BlackboxCheckResult:
"""黑盒校验单表结果"""
layer: str # "API_ODS" / "ODS_DWD" / "DWD_DWS"
source_table: str # 源表名
target_table: str # 目标表名
source_count: int # 源记录数
target_count: int # 目标记录数
count_diff: int # 差异数
amount_diffs: list # 金额差异列表
missing_keys: list # 缺失记录主键
mismatch_count: int # 内容不一致数
```
## 数据模型
### Debug 报告结构
```python
@dataclass
class DebugReport:
"""Debug 报告数据模型"""
title: str # 报告标题
generated_at: datetime # 生成时间
environment: dict # 环境信息DB DSN, API base, store_id
# 分层调试结果
ods_results: list[DebugResult] # ODS 层调试结果
dwd_results: list[DebugResult] # DWD 层调试结果
dws_results: list[DebugResult] # DWS 层调试结果
index_results: list[DebugResult] # INDEX 层调试结果
orchestration_results: list[DebugResult] # 编排层调试结果
# 黑盒校验结果
blackbox_results: list[BlackboxCheckResult]
# 全量刷新结果
full_refresh: dict # {status, layers, counts, duration}
verification: dict # {status, total_tables, consistent, backfilled}
# 性能分析
performance_report: dict # {layer_timings, bottlenecks, recommendations}
# 架构优化
architecture_report: dict # {structure_analysis, redundancies, simplification_suggestions}
# 汇总
total_issues: int # 发现的问题总数
fixed_issues: int # 已修复的问题数
remaining_issues: int # 遗留问题数
```
### 黑盒校验数据流
```mermaid
flowchart TD
API[上游 API] -->|iter_paginated| COUNT_API[API 记录数]
API -->|抽样100条| SAMPLE[抽样记录集]
ODS[(ods.* 表)] -->|SELECT COUNT| COUNT_ODS[ODS 记录数]
ODS -->|可疑值检测| SUSPECT[可疑值: 边缘值/空值/重复]
DWD[(dwd.* 表)] -->|SELECT COUNT| COUNT_DWD[DWD 记录数]
DWS[(dws.* 表)] -->|SELECT SUM| SUM_DWS[DWS 汇总值]
COUNT_API --> CMP1{API vs ODS<br/>记录数对比}
COUNT_ODS --> CMP1
COUNT_ODS --> CMP2{ODS vs DWD<br/>记录数+金额对比}
COUNT_DWD --> CMP2
COUNT_DWD --> CMP3{DWD vs DWS<br/>聚合一致性}
SUM_DWS --> CMP3
SAMPLE --> CMP4{抽样逐字段比对<br/>API vs ODS 100条}
ODS --> CMP4
SUSPECT --> CMP5{可疑值分析<br/>追溯上游原因}
CMP1 --> RPT[校验报告]
CMP2 --> RPT
CMP3 --> RPT
CMP4 --> RPT
CMP5 --> RPT
```
## 正确性属性
*属性是在系统所有有效执行中都应成立的特征或行为——本质上是关于系统应该做什么的形式化陈述。属性是人类可读规范与机器可验证正确性保证之间的桥梁。*
基于前置分析,以下属性覆盖了可自动化测试的验收标准。本项目的许多需求(特别是需求 8-12 的黑盒校验和全量刷新)依赖真实数据库和 API 连接,属于集成测试范畴,不适合属性测试。属性测试聚焦于可用 FakeDB/FakeAPI 验证的核心逻辑。
### Property 1: ODS 任务提取记录数一致性
*对任意* ODS 任务和 FakeAPI 提供的任意非空记录列表,任务执行后 FakeDB 接收到的记录数应等于 API 提供的记录数减去被跳过的记录数(缺失主键 + 重复哈希)。
**Validates: Requirements 1.1, 1.2**
### Property 2: ODS 冲突处理策略正确性
*对任意* `ods_conflict_mode` 配置值nothing/backfill/updateBaseOdsTask 生成的 SQL 语句应包含对应的冲突处理子句nothing → `DO NOTHING`backfill → `COALESCE`update → `IS DISTINCT FROM`
**Validates: Requirements 1.3**
### Property 3: ODS 跳过缺失主键记录
*对任意*包含缺失主键字段的记录集合BaseOdsTask 的 skipped 计数应等于缺失主键的记录数,且这些记录不应出现在写入的行中。
**Validates: Requirements 1.4**
### Property 4: ODS content_hash 去重
*对任意*两条内容相同的 ODS 记录(仅 fetched_at 不同),计算出的 content_hash 应相同;当已有记录的 content_hash 与新记录相同时,新记录应被跳过。
**Validates: Requirements 1.5**
### Property 5: ODS 快照删除标记
*对任意*启用 `snapshot_missing_delete` 的 ODS 任务,当 API 返回的记录集是已有记录集的真子集时,差集中的记录应被标记为 `is_delete=1`
**Validates: Requirements 1.7**
### Property 6: DWD FACT_MAPPINGS 列映射完整性
*对任意* FACT_MAPPINGS 中的映射条目 `(dwd_col, ods_expr, cast_type)`,当 `ods_expr` 是简单列名时,该列应存在于对应的 ODS 源表中。
**Validates: Requirements 2.4**
### Property 7: DWD only_tables 过滤
*对任意*非空的 `dwd.only_tables` 配置列表DwdLoadTask 处理的表集合应是配置列表与 TABLE_MAP 键集合的交集。
**Validates: Requirements 2.6**
### Property 8: DWS 分段累加一致性
*对任意*时间窗口和分段配置BaseTask 的 `_accumulate_counts` 方法对各分段计数的累加结果应等于各分段计数的逐键求和。
**Validates: Requirements 3.3**
### Property 9: PipelineRunner Flow 层解析
*对任意*有效的 Flow 名称PIPELINE_LAYERS 的键PipelineRunner 解析出的层列表应与 PIPELINE_LAYERS 中定义的值完全一致。
**Validates: Requirements 5.1, 10.2**
### Property 10: PipelineRunner 无效 Flow 拒绝
*对任意*不在 PIPELINE_LAYERS 键集合中的字符串PipelineRunner.run() 应抛出 ValueError。
**Validates: Requirements 5.2**
### Property 11: TaskExecutor 工具类任务跳过游标
*对任意*被 TaskRegistry 标记为 `requires_db_config=False` 的任务代码TaskExecutor 应通过 `_run_utility_task` 路径执行,不调用 CursorManager 和 RunTracker。
**Validates: Requirements 5.5**
### Property 12: CLI data_source 解析
*对任意* `--data-source` 参数值online/offline/hybrid`--pipeline-flow` 参数值FULL/FETCH_ONLY/INGEST_ONLY`resolve_data_source` 应返回正确的映射值,且 `--data-source` 优先于 `--pipeline-flow`
**Validates: Requirements 6.3, 6.4**
### Property 13: AppConfig 优先级合并
*对任意*嵌套字典 DEFAULTS 和 CLI 覆盖,`_deep_merge` 后 CLI 中的键值应覆盖 DEFAULTS 中的同名键值,未被覆盖的键应保持原值。
**Validates: Requirements 7.1**
### Property 14: AppConfig store_id 验证
*对任意*非整数字符串作为 `app.store_id`AppConfig._normalize 应抛出 SystemExit。
**Validates: Requirements 7.2**
### Property 15: AppConfig DSN 组装
*对任意* host、port、name、user、password 组合db.dsn 为空时AppConfig._normalize 应组装出格式为 `postgresql://{user}:{password}@{host}:{port}/{name}` 的 DSN 字符串。
**Validates: Requirements 7.3**
### Property 16: AppConfig 点号路径 get
*对任意*嵌套字典和有效的点号路径,`config.get(path)` 应返回路径对应的值;对无效路径应返回 default 参数值。
**Validates: Requirements 7.4**
## 错误处理
### 数据库连接错误
- 调试脚本在启动时验证数据库连接,连接失败时记录错误详情并在报告中标注
- 单表处理失败时回滚该表事务继续处理后续表DWD 层已实现此逻辑)
- 全量刷新过程中连接断开时,利用 `DatabaseConnection.ensure_open()` 尝试重连
### API 连接错误
- APIClient 内置重试机制(`retry_max=3`,指数退避)
- API 返回非 0 code 时抛出 ValueError由上层捕获并记录
- Token 过期时在报告中标注,提示用户更新 `.env` 中的 `API_TOKEN`
### 任务执行错误
- ODS 任务:数据库异常时回滚并递增 errors 计数
- DWD 任务:单表失败时回滚该表,继续后续表,最终汇总错误
- DWS/INDEX 任务:继承 BaseTask 的异常处理,回滚后重新抛出
- 工具类任务:异常直接向上传播,不影响游标和运行记录
### 数据质量错误
- 黑盒校验发现的不一致记录在报告中详细列出主键
- 金额差异超过阈值时标记为 WARN 级别
- 校验后自动补齐通过 `run_backfill` 执行,补齐失败的记录单独记录
## 测试策略
### 双轨测试方法
本项目采用单元测试 + 属性测试的双轨方法:
- **属性测试**:使用 `hypothesis` 库验证上述 16 个正确性属性,每个属性至少运行 100 次迭代
- **单元测试**:使用 `pytest` 验证具体示例、边界情况和错误条件
- **集成测试**:使用真实数据库(`TEST_DB_DSN`)验证端到端数据流
### 属性测试配置
- 库:`hypothesis`(已在项目依赖中)
- 最小迭代次数100
- 每个属性测试必须引用设计文档中的属性编号
- 标签格式:`Feature: etl-pipeline-debug, Property {number}: {property_text}`
### 测试文件组织
```
apps/etl/pipelines/feiqiu/tests/unit/
├── test_debug_ods_properties.py # Property 1-5: ODS 层属性测试
├── test_debug_dwd_properties.py # Property 6-8: DWD/DWS 层属性测试
├── test_debug_orchestration_properties.py # Property 9-12: 编排层属性测试
├── test_debug_config_properties.py # Property 13-16: 配置层属性测试
└── (现有测试文件保持不变)
```
### 集成测试
集成测试通过调试脚本实现,连接真实数据库和 API
- `debug_ods.py`:逐个执行 ODS 任务,验证写入结果
- `debug_dwd.py`:执行 DWD 装载,验证映射正确性
- `debug_blackbox.py`:黑盒校验,逐层对比数据完整性
- `run_full_refresh.py`:全量刷新 + 校验
### 现有测试基础设施
项目已有完善的测试工具:
- `FakeDBOperations`:拦截并记录 SQL 操作,提供 commit/rollback 计数
- `FakeAPIClient`:返回预置内存数据,记录调用参数
- `OfflineAPIClient`:从归档 JSON 回放数据
- `RealDBOperationsAdapter`:连接真实 PostgreSQL 的适配器
- `create_test_config()`:构建测试用 AppConfig

View File

@@ -0,0 +1,188 @@
# 需求文档ETL 管道全流程调试与 Debug
## 简介
`apps/etl/pipelines/feiqiu/` 下的 ETL 管道进行全流程调试,覆盖 ODS → DWD → DWS → INDEX 四层数据处理,识别并修复代码缺陷,生成 Debug 报告。调试范围包括 CLI 入口、编排层、任务执行层、数据库操作层和数据质量校验层。
## 术语表
- **ETL_Pipeline**:从上游 SaaS API 抽取数据,经 ODS → DWD → DWS 三层处理的完整数据管道
- **ODS_Layer**原始数据层Operational Data Store负责从 API 抓取数据并落地到 `ods.*`
- **DWD_Layer**明细数据层Data Warehouse Detail负责从 ODS 清洗装载,维度走 SCD2事实按时间增量
- **DWS_Layer**汇总数据层Data Warehouse Summary负责从 DWD 聚合生成业务汇总(助教业绩、财务日报等)
- **INDEX_Layer**指数算法层负责计算自定义业务指数WBI/NCI/RS/ML
- **TaskExecutor**:任务执行器,封装单个 ETL 任务的完整执行生命周期
- **PipelineRunner**Flow 编排器,根据 Flow 定义执行多层 ETL 任务
- **TaskRegistry**:任务注册表,管理 52 个已注册任务的元数据和工厂方法
- **CursorManager**:游标管理器,负责记录和推进每个任务的时间水位
- **FakeDB**:测试用伪数据库操作对象,拦截并记录 SQL 操作
- **FakeAPI**:测试用伪 API 客户端,返回预置内存数据
- **Debug_Report**:调试报告,记录发现的问题、修复措施和验证结果
## 需求
### 需求 1ODS 层任务调试
**用户故事:** 作为开发者,我希望验证 ODS 层所有任务能正确从 API 抓取数据并写入 ODS 表,以确保原始数据完整落地。
#### 验收标准
1. WHEN 使用 FakeAPI 提供样例数据执行 ODS 任务, THE TaskExecutor SHALL 正确调用 API 分页接口并提取记录列表
2. WHEN ODS 任务接收到 API 返回的记录, THE BaseOdsTask SHALL 按照 DB 表结构动态构建 INSERT 语句并写入 ODS 表
3. WHEN ODS 记录的主键已存在于目标表, THE BaseOdsTask SHALL 根据 `ods_conflict_mode` 配置执行对应的冲突处理策略nothing/backfill/update
4. WHEN ODS 记录缺少必需的主键字段值, THE BaseOdsTask SHALL 跳过该记录并递增 skipped 计数
5. WHEN `content_hash` 列存在且新记录的哈希值与已有记录相同, THE BaseOdsTask SHALL 跳过该记录以避免无意义更新
6. IF ODS 任务执行过程中发生数据库异常, THEN THE BaseOdsTask SHALL 回滚当前事务并在 counts 中递增 errors 计数
7. WHEN `snapshot_missing_delete` 配置启用且表包含 `is_delete` 列, THE BaseOdsTask SHALL 将窗口内未出现在 API 返回中的记录标记为已删除
### 需求 2DWD 层装载调试
**用户故事:** 作为开发者,我希望验证 DWD 装载任务能正确从 ODS 清洗数据并写入 DWD 表,以确保维度和事实数据准确。
#### 验收标准
1. WHEN DWD_LOAD_FROM_ODS 任务执行, THE DwdLoadTask SHALL 遍历 TABLE_MAP 中所有 DWD→ODS 映射关系并逐表处理
2. WHEN 处理维度表dim_*, THE DwdLoadTask SHALL 使用 SCD2 合并策略写入,保留历史版本
3. WHEN 处理事实表dwd_*, THE DwdLoadTask SHALL 按时间窗口增量写入,使用 FACT_ORDER_CANDIDATES 中的时间列过滤
4. WHEN ODS 源列名与 DWD 目标列名不同, THE DwdLoadTask SHALL 使用 FACT_MAPPINGS 中定义的列映射和类型转换正确转换
5. WHEN 单张 DWD 表处理失败, THE DwdLoadTask SHALL 回滚该表事务并继续处理后续表,在结果中汇总错误信息
6. WHEN `dwd.only_tables` 配置或 `DWD_ONLY_TABLES` 环境变量指定了表名列表, THE DwdLoadTask SHALL 仅处理指定的表
### 需求 3DWS 层汇总调试
**用户故事:** 作为开发者,我希望验证 DWS 层汇总任务能正确从 DWD 聚合生成业务报表数据,以确保汇总结果准确。
#### 验收标准
1. WHEN DWS 汇总任务执行, THE DWS_Task SHALL 从 DWD 层读取明细数据并按业务规则聚合写入 DWS 表
2. WHEN TaskRegistry 按 "DWS" 层查询任务列表, THE TaskRegistry SHALL 返回所有 15 个已注册的 DWS 层任务代码
3. WHEN DWS 任务的时间窗口跨越多个分段, THE DWS_Task SHALL 按分段逐段处理并累加计数结果
### 需求 4INDEX 层指数算法调试
**用户故事:** 作为开发者,我希望验证 INDEX 层指数算法任务能正确计算业务指数,以确保 WBI/NCI/RS/ML 指数结果准确。
#### 验收标准
1. WHEN INDEX 层任务执行, THE INDEX_Task SHALL 从 DWD/DWS 层读取数据并按指数算法公式计算结果
2. WHEN TaskRegistry 按 "INDEX" 层查询任务列表, THE TaskRegistry SHALL 返回所有 4 个已注册的 INDEX 层任务代码DWS_WINBACK_INDEX, DWS_NEWCONV_INDEX, DWS_ML_MANUAL_IMPORT, DWS_RELATION_INDEX
### 需求 5编排层调试
**用户故事:** 作为开发者,我希望验证 PipelineRunner 和 TaskExecutor 的编排逻辑正确,以确保多层 ETL 任务按正确顺序执行。
#### 验收标准
1. WHEN PipelineRunner 接收到有效的 Flow 名称, THE PipelineRunner SHALL 按 PIPELINE_LAYERS 定义的层顺序解析并执行任务
2. IF PipelineRunner 接收到无效的 Flow 名称, THEN THE PipelineRunner SHALL 抛出 ValueError 并包含描述性错误信息
3. WHEN PipelineRunner 在 `verify_only` 模式下执行, THE PipelineRunner SHALL 跳过增量 ETL 并直接执行校验逻辑
4. WHEN PipelineRunner 在 `increment_verify` 模式下执行, THE PipelineRunner SHALL 先执行增量 ETL 再执行校验逻辑
5. WHEN TaskExecutor 执行工具类任务, THE TaskExecutor SHALL 跳过游标管理和运行记录,直接执行任务
6. WHEN TaskExecutor 执行 ODS 任务且 data_source 包含 fetch 阶段, THE TaskExecutor SHALL 使用 RecordingAPIClient 抓取并落盘后入库
7. WHEN 任务执行成功且返回有效的时间窗口, THE TaskExecutor SHALL 通过 CursorManager 推进游标水位
### 需求 6CLI 入口调试
**用户故事:** 作为开发者,我希望验证 CLI 入口能正确解析参数并启动对应的执行模式,以确保命令行操作可靠。
#### 验收标准
1. WHEN CLI 接收到 `--pipeline` 参数, THE CLI SHALL 进入 Flow 模式并使用 PipelineRunner 执行
2. WHEN CLI 接收到 `--tasks` 参数但无 `--pipeline`, THE CLI SHALL 进入传统模式并使用 TaskExecutor 直接执行任务列表
3. WHEN CLI 接收到 `--data-source` 参数, THE CLI SHALL 使用指定的数据源模式online/offline/hybrid
4. WHEN CLI 接收到已弃用的 `--pipeline-flow` 参数, THE CLI SHALL 映射为对应的 `data_source` 值并发出 DeprecationWarning
5. WHEN CLI 未指定时间窗口参数, THE CLI SHALL 使用 `--lookback-hours`(默认 24 小时)计算回溯窗口
### 需求 7配置体系调试
**用户故事:** 作为开发者,我希望验证配置加载和合并逻辑正确,以确保 DEFAULTS < ENV < CLI 的优先级链可靠。
#### 验收标准
1. WHEN AppConfig.load 被调用, THE AppConfig SHALL 按 DEFAULTS → ENV → CLI 的优先级深度合并配置
2. WHEN 配置中 `app.store_id` 缺失或非整数, THE AppConfig SHALL 抛出 SystemExit 并包含描述性错误信息
3. WHEN 配置中 `db.dsn` 为空, THE AppConfig SHALL 从 host/port/name/user/password 组装 DSN 字符串
4. WHEN 使用点号路径调用 `config.get()`, THE AppConfig SHALL 正确遍历嵌套字典并返回对应值
### 需求 8数据质量校验调试
**用户故事:** 作为开发者,我希望验证数据完整性校验逻辑能正确检测 ODS→DWD 之间的数据差异,以确保数据一致性。
#### 验收标准
1. WHEN 执行 DWD vs ODS 校验, THE IntegrityChecker SHALL 对 TABLE_MAP 中每对 DWD→ODS 表比较记录数和金额列汇总
2. WHEN 校验发现 DWD 与 ODS 记录数不一致, THE IntegrityChecker SHALL 在结果中报告 count diff 值
3. WHEN `compare_content` 配置启用, THE IntegrityChecker SHALL 通过哈希比较检测字段级内容差异并报告 mismatch 数量
### 需求 9真实数据调试
**用户故事:** 作为开发者,我希望使用真实的数据库和 API 连接进行调试,以确保发现的问题贴近生产环境。
#### 验收标准
1. THE ETL_Pipeline SHALL 使用 `apps/etl/pipelines/feiqiu/.env` 中配置的真实 API 地址和数据库 DSN 进行调试
2. WHEN 执行调试任务, THE ETL_Pipeline SHALL 连接真实 PostgreSQL 实例test_etl_feiqiu 数据库)验证数据读写
3. WHEN 执行调试任务, THE ETL_Pipeline SHALL 调用真实上游 SaaS API 验证数据抓取和分页逻辑
4. IF 真实 API 或数据库连接失败, THEN THE ETL_Pipeline SHALL 记录连接错误详情并在 Debug 报告中标注
### 需求 10全量数据更新与校验
**用户故事:** 作为开发者,我希望在调试完成后执行 2026-01-01 至 2026-02-16 的全量数据更新和校验,以确保历史数据完整一致。
#### 验收标准
1. WHEN 调试修复完成后, THE ETL_Pipeline SHALL 使用 `api_full` Flow 执行 2026-01-01 00:00 至 2026-02-16 00:00 的全量数据更新
2. WHEN 全量更新执行, THE PipelineRunner SHALL 按 ODS → DWD → DWS → INDEX 顺序依次处理所有层
3. WHEN 全量更新完成后, THE ETL_Pipeline SHALL 执行 `increment_verify` 模式对同一时间窗口进行数据一致性校验
4. WHEN 校验发现数据不一致, THE IntegrityChecker SHALL 自动执行补齐操作并记录补齐结果
5. THE Debug_Report SHALL 包含全量更新的执行统计(各层记录数、耗时)和校验结果摘要
### 需求 11Debug 报告生成
**用户故事:** 作为开发者,我希望获得一份结构化的 Debug 报告,记录所有发现的问题和修复措施,以便追溯和复查。
#### 验收标准
1. THE Debug_Report SHALL 包含以下章节:概述、发现的问题列表、修复措施、验证结果、全量更新统计、遗留问题
2. WHEN 发现代码缺陷, THE Debug_Report SHALL 记录缺陷位置(文件路径+行号)、缺陷描述、严重程度和修复方案
3. WHEN 修复已验证通过, THE Debug_Report SHALL 记录验证方式(单元测试/属性测试/手动验证)和验证结果
4. THE Debug_Report SHALL 输出为 Markdown 文件,存放在 `apps/etl/pipelines/feiqiu/docs/reports/` 目录下
### 需求 12黑盒数据完整性校验
**用户故事:** 作为检查者,我希望以黑盒视角从 API 源数据出发,逐层对比各 Schema 各表的数据是否完整,以独立验证 ETL 管道的正确性。
#### 验收标准
1. WHEN 执行黑盒校验, THE IntegrityChecker SHALL 从上游 API 重新拉取指定时间窗口的源数据作为基准
2. WHEN 获取到 API 源数据后, THE IntegrityChecker SHALL 将 API 记录数与 ODS 表记录数逐端点对比,报告缺失和多余记录
3. WHEN ODS 层校验完成后, THE IntegrityChecker SHALL 将 ODS 表记录数与 DWD 表记录数逐映射对比,报告数量差异
4. WHEN DWD 层校验完成后, THE IntegrityChecker SHALL 验证 DWS 汇总表的聚合结果与 DWD 明细数据的一致性
5. WHEN 校验发现金额类字段汇总不一致, THE IntegrityChecker SHALL 报告差异金额和涉及的具体记录主键
6. THE IntegrityChecker SHALL 生成逐层校验报告,包含每张表的记录数对比、金额汇总对比和内容哈希差异统计
7. WHEN 校验发现缺失记录, THE IntegrityChecker SHALL 输出缺失记录的主键列表,便于定位补齐
8. WHEN 执行黑盒校验, THE IntegrityChecker SHALL 检测可疑值(边缘值、空值、重复记录等),分析可能的流程问题并追溯原因
9. WHEN 全量更新完成后, THE IntegrityChecker SHALL 从新数据中抽样 100 条记录,逐字段与上游 API 源数据比对,验证字段级一致性
### 需求 13性能分析
**用户故事:** 作为开发者,我希望分析 ETL 整体流程的性能瓶颈,在保证稳定和数据处理结果正确的基础上提高数据处理性能。
#### 验收标准
1. THE Performance_Analyzer SHALL 统计各层ODS/DWD/DWS/INDEX和各任务的执行耗时
2. THE Performance_Analyzer SHALL 识别耗时最长的前 5 个任务作为性能瓶颈
3. THE Performance_Analyzer SHALL 分析数据库查询的执行计划,识别缺失索引和全表扫描
4. THE Performance_Analyzer SHALL 分析 API 调用的响应时间和分页效率
5. THE Performance_Analyzer SHALL 生成性能优化报告,包含瓶颈分析和具体优化建议,存放在 `apps/etl/pipelines/feiqiu/docs/reports/` 目录下
### 需求 14架构优化分析
**用户故事:** 作为开发者,我希望分析 ETL 整体结构,在保证稳定和数据处理结果正确的基础上精简架构。
#### 验收标准
1. THE Architecture_Analyzer SHALL 分析代码结构,识别重复代码和冗余模块
2. THE Architecture_Analyzer SHALL 评估各层之间的耦合度,识别可解耦的组件
3. THE Architecture_Analyzer SHALL 分析任务注册表中 52 个任务的分类合理性
4. THE Architecture_Analyzer SHALL 生成架构优化报告,包含结构分析、冗余识别和精简建议,存放在 `apps/etl/pipelines/feiqiu/docs/reports/` 目录下

View File

@@ -0,0 +1,168 @@
# 实现计划ETL 管道全流程调试与 Debug
## 概述
按五阶段策略实现 ETL 管道全流程调试:分层单元调试 → 全量数据刷新(内嵌计时,边执行边 Debug→ 黑盒数据校验 → 架构优化分析 → Debug 报告生成(含性能分析)。性能计时从全量刷新阶段开始就嵌入采集,报告阶段仅做分析和输出。调试脚本放置在 `apps/etl/pipelines/feiqiu/scripts/debug/` 目录下。
## 任务
- [x] 1. 阶段1分层单元调试 - ODS 层
- [x] 1.1 编写 `scripts/debug/debug_ods.py` 调试脚本
- 连接真实 API 和数据库(从 `.env` 加载配置)
- 逐个执行 23 个 ODS 任务(小窗口,如最近 2 小时)
- 验证每个任务的返回结果status、countsfetched/inserted/updated/skipped/errors
- 检查 ODS 表实际写入行数是否与 counts 一致
- 记录每个任务的执行结果到 DebugResult 列表
- _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 9.1, 9.2, 9.3_
- [x] 1.2 编写 ODS 层属性测试 `tests/unit/test_debug_ods_properties.py`
- **Property 1: ODS 任务提取记录数一致性**
- **Validates: Requirements 1.1, 1.2**
- **Property 2: ODS 冲突处理策略正确性**
- **Validates: Requirements 1.3**
- **Property 3: ODS 跳过缺失主键记录**
- **Validates: Requirements 1.4**
- **Property 4: ODS content_hash 去重**
- **Validates: Requirements 1.5**
- **Property 5: ODS 快照删除标记**
- **Validates: Requirements 1.7**
- [x] 2. 阶段1分层单元调试 - DWD 层
- [x] 2.1 编写 `scripts/debug/debug_dwd.py` 调试脚本
- 执行 DWD_LOAD_FROM_ODS 任务
- 验证 TABLE_MAP 中每对 DWD→ODS 映射的处理结果
- 检查维度表 SCD2 版本链完整性
- 检查事实表时间窗口增量写入正确性
- 验证 FACT_MAPPINGS 列映射和类型转换
- 记录每张表的处理结果inserted/updated/errors
- _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 9.1, 9.2_
- [x] 2.2 编写 DWD 层属性测试 `tests/unit/test_debug_dwd_properties.py`
- **Property 6: DWD FACT_MAPPINGS 列映射完整性**
- **Validates: Requirements 2.4**
- **Property 7: DWD only_tables 过滤**
- **Validates: Requirements 2.6**
- **Property 8: DWS 分段累加一致性**
- **Validates: Requirements 3.3**
- [x] 3. 阶段1分层单元调试 - DWS 和 INDEX 层
- [x] 3.1 编写 `scripts/debug/debug_dws.py` 调试脚本
- 逐个执行 15 个 DWS 汇总任务
- 验证每个任务的返回结果和 DWS 表写入情况
- 检查汇总数据与 DWD 明细数据的一致性(抽样验证)
- _Requirements: 3.1, 3.2, 3.3, 9.1, 9.2_
- [x] 3.2 编写 `scripts/debug/debug_index.py` 调试脚本
- 执行 4 个 INDEX 层任务WBI/NCI/RS/ML
- 验证指数计算结果的合理性(非空、范围检查)
- _Requirements: 4.1, 4.2, 9.1, 9.2_
- [x] 4. 阶段1分层单元调试 - 编排层和配置层
- [x] 4.1 编写 `scripts/debug/debug_orchestration.py` 调试脚本
- 验证 PipelineRunner 的 Flow 解析逻辑(所有 7 种 Flow
- 验证 TaskExecutor 的任务分发逻辑ODS/DWD/DWS/工具类)
- 验证 CursorManager 的游标推进逻辑
- 验证 CLI 参数解析(传统模式 vs Flow 模式)
- _Requirements: 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 6.1, 6.2, 6.3, 6.4, 6.5_
- [x] 4.2 编写编排层属性测试 `tests/unit/test_debug_orchestration_properties.py`
- **Property 9: PipelineRunner Flow 层解析**
- **Validates: Requirements 5.1, 10.2**
- **Property 10: PipelineRunner 无效 Flow 拒绝**
- **Validates: Requirements 5.2**
- **Property 11: TaskExecutor 工具类任务跳过游标**
- **Validates: Requirements 5.5**
- **Property 12: CLI data_source 解析**
- **Validates: Requirements 6.3, 6.4**
- [x] 4.3 编写配置层属性测试 `tests/unit/test_debug_config_properties.py`
- **Property 13: AppConfig 优先级合并**
- **Validates: Requirements 7.1**
- **Property 14: AppConfig store_id 验证**
- **Validates: Requirements 7.2**
- **Property 15: AppConfig DSN 组装**
- **Validates: Requirements 7.3**
- **Property 16: AppConfig 点号路径 get**
- **Validates: Requirements 7.4**
- [x] 5. 检查点 - 阶段1 完成
- 确保所有单元调试脚本可运行,所有属性测试通过,询问用户是否有问题。
- [x] 6. 阶段2全量数据刷新内嵌计时边执行边 Debug
- [x] 6.1 编写 `scripts/debug/run_full_refresh.py` 全量刷新脚本
- 使用 `api_full` Flow 执行 2026-01-01 00:00 至 2026-02-16 00:00 的全量更新
- 按层逐步执行:先 ODS再 DWD再 DWS最后 INDEX
- 内嵌性能计时:记录每个任务的开始/结束时间、每层的总耗时、API 调用响应时间,计时的项目颗粒度尽可能精细。
- 每层执行后检查结果,发现错误时记录并尝试修复
- 支持从失败的层/任务重试(断点续跑)
- 全量更新完成后执行 `increment_verify` 校验
- 校验发现不一致时自动补齐
- 将计时数据和执行统计(记录数、耗时)写入 JSON 中间文件供后续性能分析使用
- _Requirements: 10.1, 10.2, 10.3, 10.4, 10.5, 13.1, 13.4, 9.1, 9.2, 9.3_
- [x] 6.2 执行全量刷新并修复发现的 Bug
- 运行 `run_full_refresh.py`
- 对执行过程中发现的每个 Bug定位原因、修复代码、重试验证
- 将所有发现的问题和修复记录到 DebugResult 列表
- _Requirements: 10.1, 10.2, 10.3, 10.4_
- [x] 7. 检查点 - 阶段2 完成
- 确保全量刷新成功完成,所有测试通过,询问用户是否有问题。
- [x] 8. 阶段3黑盒数据校验
- [x] 8.1 编写 `scripts/debug/debug_blackbox.py` 黑盒校验脚本
- API → ODS逐端点从 API 拉取数据,与 ODS 表记录数对比
- ODS → DWD按 TABLE_MAP 逐对比较记录数和金额列汇总
- DWD → DWS验证汇总表聚合结果与明细数据一致性
- 可疑值检测:扫描各表中的边缘值、空值、重复记录,分析可能的流程问题
- 抽样比对:从新数据中随机抽样 100 条记录,逐字段与上游 API 源数据比对
- 输出缺失记录主键列表和差异金额详情
- 生成逐层校验报告
- _Requirements: 12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9_
- [x] 8.2 执行黑盒校验并记录结果
- 运行 `debug_blackbox.py`
- 分析校验结果,对发现的不一致追溯原因
- 将校验结果记录到 BlackboxCheckResult 列表
- _Requirements: 12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9_
- [x] 9. 检查点 - 阶段3 完成
- 确保黑盒校验完成,所有测试通过,询问用户是否有问题。
- [x] 10. 阶段4架构优化分析
- [x] 10.1 编写 `scripts/debug/analyze_architecture.py` 架构分析脚本
- 分析代码结构:模块依赖关系、文件大小、函数复杂度
- 识别重复代码和冗余模块
- 评估各层之间的耦合度
- 分析 52 个任务的分类合理性
- 生成架构优化报告Markdown存放在 `docs/reports/`
- _Requirements: 14.1, 14.2, 14.3, 14.4_
- [x] 11. 阶段5Debug 报告生成(含性能分析)
- [x] 11.1 编写 `scripts/debug/analyze_performance.py` 性能分析脚本
- 读取全量刷新阶段采集的计时 JSON 中间文件
- 统计各层ODS/DWD/DWS/INDEX和各任务的执行耗时
- 识别耗时最长的前 5 个任务作为性能瓶颈
- 分析关键 SQL 查询的执行计划EXPLAIN ANALYZE
- 分析 API 调用的响应时间和分页效率
- 生成性能优化报告Markdown存放在 `docs/reports/`
- _Requirements: 13.1, 13.2, 13.3, 13.4, 13.5_
- [x] 11.2 编写 `scripts/debug/generate_report.py` 报告生成脚本
- 汇总所有阶段的调试结果
- 生成结构化 Markdown 报告,包含:概述、发现的问题列表、修复措施、验证结果、全量更新统计、黑盒校验结果、性能分析摘要、架构优化摘要、遗留问题
- 输出到 `apps/etl/pipelines/feiqiu/docs/reports/debug_report_YYYYMMDD.md`
- _Requirements: 11.1, 11.2, 11.3, 11.4_
- [x] 12. 最终检查点 - 全部完成
- 确保所有测试通过,所有报告已生成,询问用户是否有问题。
## 备注
- 标记 `*` 的任务为可选任务,可跳过以加快 MVP 进度
- 每个任务引用具体需求以确保可追溯性
- 检查点确保增量验证
- 属性测试验证通用正确性属性
- 单元测试验证具体示例和边界情况
- 调试脚本使用真实 API 和数据库连接(`.env` 配置)
- 全量刷新采用迭代式:发现 Bug 即修复并重试