# 生成 ETL 全流程联调综合报告 # 输出路径:{SYSTEM_LOG_ROOT}/{date}__etl_integration_report.md # 环境变量 SYSTEM_LOG_ROOT 缺失时报错终止。 # 用法:cd C:\NeoZQYY && python scripts/ops/gen_integration_report.py import os import sys from pathlib import Path from dotenv import load_dotenv # 加载根 .env load_dotenv(Path(__file__).resolve().parents[2] / ".env") SYSTEM_LOG_ROOT = os.environ.get("SYSTEM_LOG_ROOT") if not SYSTEM_LOG_ROOT: print("ERROR: 环境变量 SYSTEM_LOG_ROOT 未设置,无法输出报告。", file=sys.stderr) sys.exit(1) output_dir = Path(SYSTEM_LOG_ROOT) output_dir.mkdir(parents=True, exist_ok=True) REPORT_DATE = "2026-02-24" output_path = output_dir / f"{REPORT_DATE}__etl_integration_report.md" # ── 报告内容 ────────────────────────────────────────────────────────────────── REPORT = r"""# ETL 全流程联调报告 > 生成时间:2026-02-24 > execution_id: `41938155-db8c-4eec-9b81-9e5aef42fb8a` > run_uuid: `f764a42487c34e0f9bd19e4fa9c57f03` --- ## 1. 执行概要 | 项目 | 值 | |------|-----| | Flow | `api_full`(API → ODS → DWD → DWS → INDEX) | | 处理模式 | `full_window`(全窗口) | | 时间窗口 | 2025-11-01 ~ 2026-02-20(自定义) | | 窗口切分 | 30 天/切片,共 4 个切片 | | force_full | 是 | | 任务数 | 41 个常用任务(`is_common=True`) | | 开始时间 | 2026-02-24 12:27:22 | | 结束时间 | 2026-02-24 13:05:43 | | 总耗时 | 38m22s | | 退出码 | 0 | | 最终状态 | **success** | | 数据统计 | 225,760 fetched / 13,437 inserted / 225,648 updated | ### 窗口切片 | 切片 | 窗口范围 | |------|---------| | 1 | 2025-10-31 22:00 ~ 2025-11-30 22:00 | | 2 | 2025-11-30 22:00 ~ 2025-12-30 22:00 | | 3 | 2025-12-30 22:00 ~ 2026-01-29 22:00 | | 4 | 2026-01-29 22:00 ~ 2026-02-20 02:00 | --- ## 2. 性能报告 ### 2.1 阶段耗时汇总 | 阶段 | 墙钟耗时 | 占比 | 状态 | |------|---------|------|------| | ODS | 31m17s | 81.8% | ✅ 全部成功(21 任务 + 1 跳过) | | DWD | 2m30s | 6.5% | ✅ 全部成功(1 任务) | | DWS | 4m29s | 11.7% | ⚠️ 7 成功 / 8 失败 | | INDEX | <1s | 0.0% | ❌ 3 任务全部失败(级联) | | **合计** | **38m16s** | **100%** | 29 成功 / 11 失败 / 1 跳过 | ### 2.2 Top-5 耗时瓶颈 | 排名 | 任务 | 阶段 | 耗时 | 备注 | |------|------|------|------|------| | 1 | ODS_PLATFORM_COUPON | ODS | 10m41s | 数据量大,4 切片均 >2m | | 2 | ODS_TABLE_USE | ODS | 4m23s | 每切片 ~1m | | 3 | ODS_GROUP_BUY_REDEMPTION | ODS | 4m22s | 每切片 ~1m | | 4 | ODS_PAYMENT | ODS | 4m7s | 每切片 ~1m | | 5 | DWS_ASSISTANT_DAILY | DWS | 2m43s | 聚合计算密集 | > Top-5 合计 26m16s,占总耗时 68.6%。ODS 阶段 API 拉取是主要瓶颈。 ### 2.3 ODS 任务耗时明细 | 任务 | 切片数 | 总耗时 | 状态 | |------|--------|--------|------| | ODS_PLATFORM_COUPON | 4 | 10m41s | ✅ | | ODS_TABLE_USE | 4 | 4m23s | ✅ | | ODS_GROUP_BUY_REDEMPTION | 4 | 4m22s | ✅ | | ODS_PAYMENT | 4 | 4m7s | ✅ | | ODS_MEMBER_BALANCE | 4 | 2m8s | ✅ | | ODS_SETTLEMENT_RECORDS | 4 | 1m45s | ✅ | | ODS_TABLE_FEE_DISCOUNT | 4 | 54s | ✅ | | ODS_INVENTORY_CHANGE | 4 | 48s | ✅ | | ODS_MEMBER_CARD | 4 | 35s | ✅ | | ODS_ASSISTANT_LEDGER | 4 | 24s | ✅ | | ODS_MEMBER | 4 | 14s | ✅ | | ODS_INVENTORY_STOCK | 4 | 9s | ✅ | | ODS_ASSISTANT_ACCOUNT | 4 | 7s | ✅ | | ODS_STORE_GOODS | 4 | 7s | ✅ | | ODS_REFUND | 4 | 4s | ✅ | | ODS_RECHARGE_SETTLE | 4 | 4s | ✅ | | ODS_TENANT_GOODS | 4 | 4s | ✅ | | ODS_TABLES | 4 | 2s | ✅ | | ODS_GROUP_PACKAGE | 4 | 2s | ✅ | | ODS_GOODS_CATEGORY | 4 | 1s | ✅ | | ODS_STORE_GOODS_SALES | 4 | 1s | ✅ | | ODS_ASSISTANT_ABOLISH | — | — | ⏭️ 跳过(未启用) | ### 2.4 DWD 任务耗时明细 | 任务 | 切片数 | 总耗时 | 状态 | |------|--------|--------|------| | DWD_LOAD_FROM_ODS | 4 | 2m30s | ✅ | ### 2.5 DWS 任务耗时明细 | 任务 | 切片数 | 总耗时 | 状态 | |------|--------|--------|------| | DWS_ASSISTANT_DAILY | 4 | 2m43s | ✅ | | DWS_ASSISTANT_CUSTOMER | 4 | 1m32s | ✅ | | DWS_GOODS_STOCK_MONTHLY | 4 | 1s | ✅ | | DWS_BUILD_ORDER_SUMMARY | 0 | 1s | ✅ | | DWS_GOODS_STOCK_DAILY | 4 | <1s | ✅ | | DWS_GOODS_STOCK_WEEKLY | 4 | <1s | ✅ | | DWS_ASSISTANT_SALARY | 4 | <1s | ✅ | | DWS_MEMBER_CONSUMPTION | — | — | ❌ 失败(根因) | | DWS_MEMBER_VISIT | — | — | ❌ 级联失败 | | DWS_FINANCE_DAILY | — | — | ❌ 级联失败 | | DWS_FINANCE_RECHARGE | — | — | ❌ 级联失败 | | DWS_FINANCE_INCOME_STRUCTURE | — | — | ❌ 级联失败 | | DWS_FINANCE_DISCOUNT_DETAIL | — | — | ❌ 级联失败 | | DWS_ASSISTANT_MONTHLY | — | — | ❌ 级联失败 | | DWS_ASSISTANT_FINANCE | — | — | ❌ 级联失败 | ### 2.6 INDEX 任务耗时明细 | 任务 | 状态 | |------|------| | DWS_WINBACK_INDEX | ❌ 级联失败 | | DWS_NEWCONV_INDEX | ❌ 级联失败 | | DWS_RELATION_INDEX | ❌ 级联失败 | --- ## 3. DEBUG 报告 ### 3.1 错误摘要 共发现 **1 个根因错误**,导致 **10 个任务级联失败**。 ### 3.2 WARNING:ODS_ASSISTANT_ABOLISH 未启用 - **级别**:低优先级 - **现象**:日志输出 `ODS_ASSISTANT_ABOLISH 未启用或不存在` - **原因**:任务注册表中该任务标记为 `is_common=False`(非活跃),但仍在全选列表中 - **影响**:无,任务被正常跳过 - **建议**:无需处理,属于预期行为 ### 3.3 ROOT CAUSE:DWS_MEMBER_CONSUMPTION 失败 **根因分析**:两个 BUG 叠加导致任务失败。 #### BUG-1:FDW 外部表未部署 - **现象**:查询 `fdw_app.member_birthday_manual` 时报错(外部表不存在) - **原因**:`db/fdw/setup_fdw_reverse.sql` 中定义的反向 FDW 外部表未在测试库部署 - **影响**:主 SQL 执行失败,触发 rollback,进入 `sql_fallback` 分支 #### BUG-2:sql_fallback 列名错误 - **现象**:fallback SQL 引用了不存在的列 `tenant_member_id` - **原因**:实际列名应为 `member_id`,fallback SQL 未与表结构同步 - **影响**:fallback 也失败,事务进入 `InFailedSqlTransaction` 状态 ### 3.4 CASCADE FAILURE:10 个任务级联失败 - **触发点**:DWS_MEMBER_CONSUMPTION 失败后,数据库连接的事务处于 `InFailedSqlTransaction` 状态 - **根因**:`run_tasks` 的 `except` 块未调用 `self.db.rollback()`,导致后续所有任务在同一个已失败的事务中执行 - **级联任务**(共 10 个): 1. DWS_MEMBER_VISIT 2. DWS_FINANCE_DAILY 3. DWS_FINANCE_RECHARGE 4. DWS_FINANCE_INCOME_STRUCTURE 5. DWS_FINANCE_DISCOUNT_DETAIL 6. DWS_ASSISTANT_MONTHLY 7. DWS_ASSISTANT_FINANCE 8. DWS_WINBACK_INDEX 9. DWS_NEWCONV_INDEX 10. DWS_RELATION_INDEX ### 3.5 修复建议 | 优先级 | 修复项 | 说明 | |--------|--------|------| | **P0** | 修复 SQL 列名 | `tenant_member_id` → `member_id`(DWS_MEMBER_CONSUMPTION 的 sql_fallback) | | **P0** | run_tasks except 块添加 rollback | `self.db.rollback()` 防止级联失败 | | **P1** | 部署 FDW 外部表 | 执行 `db/fdw/setup_fdw_reverse.sql` 到测试库 | --- ## 4. 黑盒测试报告 > ⏳ 待补充 — 将在 Task 5.3 完成后追加。 > > 预期内容: > - API vs ODS:通过数/总数 > - ODS vs DWD:通过数/总数 > - DWD vs DWS:表概览 > - 白名单差异统计 > - 失败表清单 > - 全链路检查报告路径引用 --- ## 附录 ### A. 完整 CLI 参数 ``` --flow api_full --processing-mode full_window --window-start 2025-11-01 --window-end 2026-02-20 --window-split day --window-split-days 30 --force-full --tasks ODS_ASSISTANT_ACCOUNT ODS_ASSISTANT_LEDGER ODS_ASSISTANT_ABOLISH ODS_SETTLEMENT_RECORDS ODS_TABLE_USE ODS_TABLE_FEE_DISCOUNT ODS_TABLES ODS_PAYMENT ODS_REFUND ODS_PLATFORM_COUPON ODS_MEMBER ODS_MEMBER_CARD ODS_MEMBER_BALANCE ODS_RECHARGE_SETTLE ODS_GROUP_PACKAGE ODS_GROUP_BUY_REDEMPTION ODS_INVENTORY_STOCK ODS_INVENTORY_CHANGE ODS_GOODS_CATEGORY ODS_STORE_GOODS ODS_STORE_GOODS_SALES ODS_TENANT_GOODS DWD_LOAD_FROM_ODS DWS_BUILD_ORDER_SUMMARY DWS_ASSISTANT_DAILY DWS_ASSISTANT_MONTHLY DWS_ASSISTANT_CUSTOMER DWS_ASSISTANT_SALARY DWS_ASSISTANT_FINANCE DWS_MEMBER_CONSUMPTION DWS_MEMBER_VISIT DWS_FINANCE_DAILY DWS_FINANCE_RECHARGE DWS_FINANCE_INCOME_STRUCTURE DWS_FINANCE_DISCOUNT_DETAIL DWS_GOODS_STOCK_DAILY DWS_GOODS_STOCK_WEEKLY DWS_GOODS_STOCK_MONTHLY DWS_WINBACK_INDEX DWS_NEWCONV_INDEX DWS_RELATION_INDEX ``` ### B. 精细计时报告 完整的窗口切片级计时数据见:`export/temp_timing_report.md` """ output_path.write_text(REPORT.strip(), encoding="utf-8") print(f"✅ 报告已生成: {output_path}")