9.7 KiB
9.7 KiB
设计文档:助教废除(Abolish)全链路清理
概述
本设计描述如何安全地从 ETL 全链路中移除"助教废除"独立数据链路。
核心思路:删除独立的废除链路(API → ODS → DWD),保留服务记录中已有的 is_trash 字段作为唯一废除判断源。
清理范围覆盖:
- ETL 任务定义(ODS 任务 + 注册表)
- DWD 加载映射(FACT_MAPPINGS + TABLE_MAP)
- DWS 聚合逻辑(死代码移除)
- DWD 验证器配置
- 数据库 DDL 和迁移脚本
- 属性测试
- 运维脚本
架构
清理前数据流
graph LR
API_Abolish["/AssistantPerformance/GetAbolitionAssistant"] --> ODS_ACR["ods.assistant_cancellation_records"]
ODS_ACR --> DWD_ATE["dwd.dwd_assistant_trash_event"]
ODS_ACR --> DWD_ATE_EX["dwd.dwd_assistant_trash_event_ex"]
DWD_ATE --> |"_extract_trash_records (死代码)"| DWS_DAILY["dws.dws_assistant_daily_detail"]
API_Service["/AssistantPerformance/GetAssistantServiceRecords"] --> ODS_ASR["ods.assistant_service_records"]
ODS_ASR --> DWD_SL_EX["dwd.dwd_assistant_service_log_ex"]
DWD_SL_EX --> |"is_trash 字段 (实际使用)"| DWS_DAILY
style API_Abolish fill:#f99,stroke:#c00
style ODS_ACR fill:#f99,stroke:#c00
style DWD_ATE fill:#f99,stroke:#c00
style DWD_ATE_EX fill:#f99,stroke:#c00
清理后数据流
graph LR
API_Service["/AssistantPerformance/GetAssistantServiceRecords"] --> ODS_ASR["ods.assistant_service_records"]
ODS_ASR --> DWD_SL_EX["dwd.dwd_assistant_service_log_ex"]
DWD_SL_EX --> |"is_trash 字段"| DWS_DAILY["dws.dws_assistant_daily_detail"]
style API_Service fill:#9f9,stroke:#090
style DWD_SL_EX fill:#9f9,stroke:#090
组件与接口
需要修改的文件清单
| 层级 | 文件 | 操作 | 需求 |
|---|---|---|---|
| ODS 任务 | tasks/ods/ods_tasks.py |
删除 OdsTaskSpec 条目 + 从默认序列移除 |
1.2, 1.3 |
| 任务注册 | orchestration/task_registry.py |
删除 ODS_ASSISTANT_ABOLISH 注册 |
1.1 |
| DWD 加载 | tasks/dwd/dwd_load_task.py |
删除 FACT_MAPPINGS 和 TABLE_MAP 条目 | 2.1–2.4 |
| DWS 日度 | tasks/dws/assistant_daily_task.py |
删除 _extract_trash_records、_build_trash_index,简化 _aggregate_by_assistant_date 签名 |
3.1–3.4 |
| DWD 验证 | tasks/verification/dwd_verifier.py |
删除废除表的 ID 和时间字段映射 | 4.1–4.4 |
| DDL | db/etl_feiqiu/schemas/dwd.sql |
删除 dwd_assistant_trash_event / _ex 的 CREATE TABLE + COMMENT |
6.1–6.2 |
| DDL | db/etl_feiqiu/schemas/ods.sql |
删除 assistant_cancellation_records 的 CREATE TABLE + COMMENT |
6.3 |
| DDL | db/etl_feiqiu/schemas/schema_dwd_doc.sql |
删除废除表的 CREATE TABLE + COMMENT | 6.4 |
| DDL | db/etl_feiqiu/schemas/schema_ODS_doc.sql |
删除废除表的 CREATE TABLE + COMMENT | 6.5 |
| DDL | db/etl_feiqiu/schemas/dws.sql |
更新 dws_assistant_daily_detail 注释 |
6.6 |
| DDL | db/etl_feiqiu/schemas/schema_dws.sql |
更新 dws_assistant_daily_detail 注释 |
6.7 |
| 迁移 | db/etl_feiqiu/migrations/ |
新建 DROP TABLE 迁移脚本 | 5.1–5.5 |
| 属性测试 | tests/test_property_1_fact_mappings.py |
删除 _REQ3_EXPECTED 和相关引用 |
7.1–7.3 |
| 运维 | scripts/ops/dataflow_analyzer.py |
删除 ODS_ASSISTANT_ABOLISH spec 条目 |
8.1 |
| 运维 | scripts/ops/gen_full_dataflow_doc.py |
删除 ODS_ASSISTANT_ABOLISH spec 条目 |
8.1 |
| 运维 | scripts/ops/etl_consistency_check.py |
删除废除相关映射 | 8.1–8.2 |
| 运维 | scripts/ops/blackbox_test_report.py |
删除废除相关映射 | 8.1–8.4 |
| 运维 | scripts/ops/field_audit.py |
删除废除表审计条目 | 8.3–8.4 |
| 运维 | scripts/ops/gen_field_review_doc.py |
删除废除表字段定义 | 8.3–8.4 |
| 运维 | scripts/ops/gen_api_field_mapping.py |
从 ODS_TABLES 列表移除 | 8.3 |
| 运维 | scripts/ops/export_dwd_field_review.py |
删除废除表条目 | 8.4 |
| 运维 | scripts/ops/check_ods_latest_indexes.py |
删除废除表索引检查 | 8.3 |
不需要修改的文件(确认安全)
| 文件 | 原因 |
|---|---|
dwd_assistant_service_log_ex 表 DDL |
保留 is_trash 等字段(需求 9) |
ods.assistant_service_records 表 DDL |
保留 is_trash 等字段(需求 9) |
assistant_monthly_task.py |
仅消费 dws_assistant_daily_detail 的 trashed_seconds/trashed_count,不直接引用废除表 |
assistant_salary_task.py |
仅消费 dws_assistant_monthly_summary,不直接引用废除表 |
数据模型
被删除的表
-- ODS 层
ods.assistant_cancellation_records -- 78 条记录
-- DWD 层
dwd.dwd_assistant_trash_event -- 主表
dwd.dwd_assistant_trash_event_ex -- 扩展表
保留的废除相关字段
-- ods.assistant_service_records 中(保留)
is_trash INT -- 废除标记
trash_reason TEXT -- 废除原因
trash_applicant_id BIGINT -- 废除申请人 ID
trash_applicant_name TEXT -- 废除申请人姓名
-- dwd.dwd_assistant_service_log_ex 中(保留)
is_trash INTEGER -- 废除标记
trash_applicant_id BIGINT -- 废除申请人 ID
trash_applicant_name VARCHAR(64) -- 废除申请人姓名
trash_reason VARCHAR(255) -- 废除原因
DWS 层字段(保留,数据来源变更说明)
-- dws.dws_assistant_daily_detail(保留,注释需更新)
trashed_seconds INTEGER -- 数据来源:dwd_assistant_service_log_ex.is_trash + income_seconds
trashed_count INTEGER -- 数据来源:dwd_assistant_service_log_ex.is_trash 计数
-- dws.dws_assistant_monthly_summary(保留)
trashed_hours NUMERIC(10,2) -- 来自 daily_detail.trashed_seconds 汇总
DWS 代码重构细节
assistant_daily_task.py 变更
删除方法:
_extract_trash_records()— 查询dwd.dwd_assistant_trash_event的 SQL,已无消费者_build_trash_index()— 构建废除索引,已不参与判断逻辑
修改方法:
extract()— 移除对_extract_trash_records的调用,移除trash_records变量transform()或调用_aggregate_by_assistant_date的地方 — 移除trash_index参数传递_aggregate_by_assistant_date()— 从签名中移除trash_index参数;is_trash判断逻辑保持不变
不变逻辑:
# 这段逻辑保持不变——通过 is_trash 字段判断废除
is_trashed = bool(record.get('is_trash', 0))
if is_trashed:
agg['trashed_seconds'] += income_seconds
agg['trashed_count'] += 1
正确性属性
正确性属性是一种在系统所有有效执行中都应成立的特征或行为——本质上是关于系统应该做什么的形式化陈述。属性是人类可读规格与机器可验证正确性保证之间的桥梁。
Property 1:废除聚合逻辑正确性(is_trash 驱动)
对任意服务记录集合,其中每条记录包含 is_trash 标记和 income_seconds 值,聚合后:
trashed_seconds应等于所有is_trash=1记录的income_seconds之和trashed_count应等于所有is_trash=1记录的数量total_service_count应等于所有is_trash=0记录的数量total_seconds应等于所有is_trash=0记录的income_seconds之和
Validates: Requirements 3.4, 9.3
Property 2:FACT_MAPPINGS 一致性(已有属性测试的回归验证)
对任意 FACT_MAPPINGS 中的表名,该表名应在 TABLE_MAP 中有对应的 ODS 源表映射,且映射的每个 DWD 列名应为合法的 SQL 标识符。
Validates: Requirements 2.1–2.4, 7.3
注:此属性已由
tests/test_property_1_fact_mappings.py实现。清理后需确保该测试仍然通过。
错误处理
迁移脚本安全性
- 所有
DROP TABLE语句使用IF EXISTS,确保幂等执行 - 迁移脚本在单个事务中执行,失败时自动回滚
- 迁移脚本包含注释说明移除原因,便于审计追溯
代码删除安全性
- 删除
_extract_trash_records和_build_trash_index前,确认无其他调用者 _aggregate_by_assistant_date移除trash_index参数后,确认所有调用点已同步更新- 保留
is_trash判断逻辑不变,确保废除统计功能不受影响
回滚策略
- DDL 变更通过迁移脚本管理,可通过反向迁移(CREATE TABLE)回滚
- 代码变更通过 Git 版本控制回滚
- ODS 表数据在删除前可选择性备份(数据量小,仅 78 条)
测试策略
属性测试
- 使用
hypothesis库进行属性测试 - 每个属性测试至少运行 100 次迭代
- 每个测试用注释标注对应的设计属性编号
Property 1 测试方案:
- 生成随机服务记录列表(包含随机
is_trash标记和income_seconds值) - 调用
_aggregate_by_assistant_date方法 - 验证
trashed_seconds/trashed_count与手动计算的期望值一致 - 标签:
Feature: assistant-abolish-cleanup, Property 1: 废除聚合逻辑正确性
Property 2 测试方案:
- 已由
tests/test_property_1_fact_mappings.py覆盖 - 清理后运行
pytest tests/ -v确认无回归 - 标签:
Feature: assistant-abolish-cleanup, Property 2: FACT_MAPPINGS 一致性
单元测试
- 验证
AssistantDailyTask不再有_extract_trash_records和_build_trash_index方法 - 验证
_aggregate_by_assistant_date签名不包含trash_index参数 - 验证 FACT_MAPPINGS 不包含废除表条目
- 验证 TABLE_MAP 不包含废除表映射
- 验证 DwdVerifier 配置不包含废除表
集成验证
- 运行现有属性测试套件:
pytest tests/ -v - 运行 ETL 单元测试:
cd apps/etl/connectors/feiqiu && pytest tests/unit - 确认所有测试通过,无回归