5.9 KiB
5.9 KiB
实施计划:DWD 第一阶段重构
概述
按照 confirmed_changes.md 中 2.1-2.4 的顺序,对 DwdLoadTask 进行低风险重构。改动集中在 dwd_load_task.py,辅以删除 base_dwd_task.py 和更新两个外部引用。每个步骤递增构建,确保无悬空代码。
任务
-
1. 统一窗口模式,去掉水位线(需求 1)
- 1.1 修改
_merge_fact_increment()签名:window_start和window_end改为必填参数(去掉| None和默认值None);删除方法体内的 watermark 分支(elif order_col:块及watermark = None赋值),统一使用WHERE fetched_at >= %s AND fetched_at < %s- 文件:
tasks/dwd/dwd_load_task.py,方法_merge_fact_increment - Requirements: 1.2, 1.4
- 文件:
- 1.2 修改
load()中事实表分支:删除use_window变量及条件判断,始终传window_start=context.window_start, window_end=context.window_end- 文件:
tasks/dwd/dwd_load_task.py,方法load - Requirements: 1.1
- 文件:
- 1.3 删除
_get_fact_watermark()方法(约 30 行)- 文件:
tasks/dwd/dwd_load_task.py - Requirements: 1.3
- 文件:
- 1.4 编写属性测试:事实表增量 SQL 始终使用窗口范围条件
- Property 1: 事实表增量 SQL 始终使用窗口范围条件
- Validates: Requirements 1.1, 1.2
- 使用
hypothesis生成随机window_start/window_end,通过FakeCursor捕获 SQL,验证 WHERE 子句包含>= %s AND < %s,不包含单边水位线条件 - 文件:
tests/test_dwd_phase1_properties.py
- 1.1 修改
-
2. 删除回补机制(需求 2)
- 2.1 删除
_merge_fact_increment()末尾的回补调用块:移除对_insert_missing_by_pk()的调用及missing_inserted相关代码- 文件:
tasks/dwd/dwd_load_task.py,方法_merge_fact_increment - Requirements: 2.3
- 文件:
- 2.2 删除
_insert_missing_by_pk()方法(约 100 行)- 文件:
tasks/dwd/dwd_load_task.py - Requirements: 2.1
- 文件:
- 2.3 删除
FACT_MISSING_FILL_TABLES常量- 文件:
tasks/dwd/dwd_load_task.py - Requirements: 2.2
- 文件:
- 2.4 编写属性测试:事实表增量不执行回补 SQL
- Property 2: 事实表增量不执行回补 SQL
- Validates: Requirements 2.3
- 通过
FakeCursor捕获所有执行的 SQL,验证无LEFT JOIN ... IS NULL模式 - 文件:
tests/test_dwd_phase1_properties.py
- 2.1 删除
-
3. 检查点 - 确保窗口统一和回补删除后测试通过
- 运行
cd apps/etl/pipelines/feiqiu && pytest tests/unit和cd C:\NeoZQYY && pytest tests/ -v,确保所有测试通过,如有问题请询问用户。
- 运行
-
4. 清理死代码和未使用常量(需求 3)
- 4.1 删除
_pick_order_column()方法和FACT_ORDER_CANDIDATES常量- 文件:
tasks/dwd/dwd_load_task.py - Requirements: 3.2, 3.3
- 文件:
- 4.2 更新外部引用:在
debug_dwd.py和integrity_checker.py中将DwdLoadTask.FACT_ORDER_CANDIDATES替换为模块级常量_TIME_COLUMN_CANDIDATES(内联相同列表)- 文件:
scripts/debug/debug_dwd.py、quality/integrity_checker.py - Requirements: 3.9
- 文件:
- 4.3 删除逐行 SCD2 方法:
_upsert_scd2_row()、_close_current_dim()、_insert_dim_row()- 文件:
tasks/dwd/dwd_load_task.py - Requirements: 3.4, 3.5, 3.6
- 文件:
- 4.4 删除
_merge_dim_type1_upsert()方法;简化_merge_dim()直接调用_merge_dim_scd2()- 文件:
tasks/dwd/dwd_load_task.py - Requirements: 3.7, 3.8
- 文件:
- 4.5 删除
base_dwd_task.py文件- 文件:
tasks/dwd/base_dwd_task.py - Requirements: 3.1
- 文件:
- 4.6 编写属性测试:维度表始终走 SCD2 路径
- Property 4: 维度表始终走 SCD2 路径
- Validates: Requirements 3.8, 5.1
- 通过 mock
_merge_dim_scd2验证_merge_dim()始终委托给它 - 文件:
tests/test_dwd_phase1_properties.py
- 4.1 删除
-
5. 修复
_build_column_mapping()参数 bug(需求 4)- 5.1 修改
_build_column_mapping()签名:添加cur和ods_table参数;更新所有调用点(_merge_dim_type1_upsert已删除,剩余调用点为_merge_dim_scd2)传入正确参数- 文件:
tasks/dwd/dwd_load_task.py - Requirements: 4.1, 4.2
- 文件:
- 5.2 编写单元测试:验证
_build_column_mapping()在fetched_at缺失时正确使用ods_table和cur参数记录日志- 文件:
apps/etl/pipelines/feiqiu/tests/unit/test_dwd_phase1_refactor.py - Requirements: 4.1
- 文件:
- 5.1 修改
-
6. 编写回归单元测试(需求 5)
- 6.1 编写单元测试:验证死代码已清理(
hasattr检查所有已删除的方法和常量)- 文件:
apps/etl/pipelines/feiqiu/tests/unit/test_dwd_phase1_refactor.py - Requirements: 1.3, 2.1, 2.2, 3.1-3.7
- 文件:
- 6.2 编写单元测试:验证外部模块导入正常(
debug_dwd.py、integrity_checker.py无 ImportError)- 文件:
apps/etl/pipelines/feiqiu/tests/unit/test_dwd_phase1_refactor.py - Requirements: 3.9
- 文件:
- 6.3 编写属性测试:事实表主增量 SQL 结构等价性
- Property 3: 事实表主增量 SQL 结构等价性
- Validates: Requirements 5.2, 5.5
- 使用
hypothesis生成随机列集合和窗口参数,通过FakeCursor捕获 SQL,验证 INSERT INTO ... ON CONFLICT 结构与预期一致 - 文件:
tests/test_dwd_phase1_properties.py
- 6.1 编写单元测试:验证死代码已清理(
-
[~] 7. 最终检查点 - 确保所有测试通过
- 运行
cd apps/etl/pipelines/feiqiu && pytest tests/unit和cd C:\NeoZQYY && pytest tests/ -v,确保所有测试通过,如有问题请询问用户。
- 运行
备注
- 标记
*的子任务为可选测试任务,可跳过以加速 MVP - 每个任务引用了具体的需求编号,确保可追溯
- 检查点确保增量验证
- 属性测试验证通用正确性属性,单元测试验证具体示例和边界情况
- 本次重构涉及
tasks/高风险路径,完成后需运行/audit