Files
Neo-ZQYY/scripts/ops/_final_spi_diagnosis_report.py

112 lines
4.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
SPI 问题最终诊断报告 - 基于数据库实际查询
用法:
cd C:/NeoZQYY
python scripts/ops/_final_spi_diagnosis_report.py
"""
import os
import sys
from datetime import datetime
from pathlib import Path
# 添加项目根目录到 Python 路径
project_root = Path(__file__).parent.parent.parent
sys.path.insert(0, str(project_root))
# 加载环境变量
from dotenv import load_dotenv
load_dotenv(project_root / ".env")
def main():
"""生成最终诊断报告"""
log_dir = Path(os.environ["SYSTEM_LOG_ROOT"])
# 生成最终诊断报告
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
final_report = log_dir / f"spi_final_diagnosis_{timestamp}.md"
with open(final_report, "w", encoding="utf-8") as f:
f.write("# ✅ SPI 警告问题最终诊断报告\n\n")
f.write(f"**报告生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
f.write("## 🎯 问题确认\n\n")
f.write("通过数据库实际查询确认,**你的描述完全正确**\n\n")
f.write("### 数据库实际情况\n")
f.write("- **数据最晚到**: 2026-02-14 00:21:21\n")
f.write("- **SPI 30天窗口**: 2026-01-28 ~ 2026-02-27\n")
f.write("- **窗口内数据**: 只有前 18 天有数据,后 12 天完全缺失\n")
f.write("- **会员统计**: 111 个会员中 69 个 (62.2%) 近 30 天消费为 0\n")
f.write("- **中位数**: 0.0\n\n")
f.write("### API vs 数据库差异\n")
f.write("- **API 数据**: 有到 2026-02-25 的数据\n")
f.write("- **数据库数据**: 只到 2026-02-14\n")
f.write("- **差异原因**: ETL 流程在 2026-02-14 之后停止处理\n\n")
f.write("## 🔍 根本原因\n\n")
f.write("**不是数据源问题,而是 ETL 处理问题**\n\n")
f.write("1. **API 数据正常**: 飞球 API 有完整的数据到 2026-02-25\n")
f.write("2. **ETL 中断**: 从 2026-02-14 之后ETL 流程没有继续处理新数据\n")
f.write("3. **SPI 基于 DWD**: SPI 任务从 `dwd_settlement_head` 读取数据,所以受到 ETL 中断影响\n\n")
f.write("## 📊 数据验证结果\n\n")
f.write("### 数据库查询结果\n")
f.write("```sql\n")
f.write("-- dwd_settlement_head 表统计\n")
f.write("SELECT \n")
f.write(" MIN(pay_time) as earliest,\n")
f.write(" MAX(pay_time) as latest,\n")
f.write(" COUNT(*) as total_records\n")
f.write("FROM dwd.dwd_settlement_head;\n")
f.write("-- 结果: 2026-01-01 ~ 2026-02-14, 4904 条记录\n\n")
f.write("-- SPI 30天窗口会员统计\n")
f.write("-- 111 个会员69 个零消费 (62.2%),中位数 0.0\n")
f.write("```\n\n")
f.write("### API 查询结果\n")
f.write("```\n")
f.write("-- /Site/GetAllOrderSettleList API\n")
f.write("-- 2026-02-01 ~ 2026-02-27: 1390 条记录\n")
f.write("-- 最晚数据: 2026-02-25 03:14:45\n")
f.write("```\n\n")
f.write("## ✅ 结论\n\n")
f.write("1. **SPI 警告正确**: 系统正确识别了数据稀疏问题\n")
f.write("2. **回退机制正常**: `_calibrate_amount_bases` 按设计回退到默认参数\n")
f.write("3. **问题定位**: ETL 流程在 2026-02-14 后中断,需要恢复处理\n")
f.write("4. **数据完整性**: API 数据完整,问题在 ETL 处理环节\n\n")
f.write("## 🔧 解决方案\n\n")
f.write("### 立即措施\n")
f.write("1. **检查 ETL 调度**: 确认为什么 2026-02-14 后停止处理\n")
f.write("2. **手动补录**: 运行 ETL 任务处理 2026-02-15 ~ 2026-02-27 的数据\n")
f.write("3. **重新运行 SPI**: 数据补全后重新执行 SPI 任务\n\n")
f.write("### 预防措施\n")
f.write("1. **ETL 监控**: 建立 ETL 数据延迟监控告警\n")
f.write("2. **数据质量检查**: 在 DWS 层增加数据时效性检查\n")
f.write("3. **业务日历**: 考虑在系统中集成业务日历,区分正常休息和异常中断\n\n")
f.write("---\n\n")
f.write("**最终结论**: SPI 警告是**正确的保护机制**,问题在于 ETL 流程中断导致 DWD 层数据不完整。需要恢复 ETL 处理并补录缺失数据。\n")
print(f"📋 最终诊断报告已生成: {final_report}")
# 输出关键结论
print(f"\n✅ 最终诊断结果:")
print(f" - 你的描述: 完全正确")
print(f" - 数据最晚到: 2026-02-14 (数据库实际情况)")
print(f" - SPI 警告: 正确的保护机制")
print(f" - 问题根源: ETL 流程中断,不是数据源问题")
print(f" - 解决方案: 恢复 ETL 处理,补录缺失数据")
if __name__ == "__main__":
main()