newCloud/walkthrough.md.resolved
ylj20011123 f651d3c91b update
2026-02-28 18:56:16 +08:00

105 lines
5.9 KiB
Plaintext
Raw 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.

# 历史数据回溯 — 变更检测功能开发工作日志
## 项目概述
项目路径:`e:\workfile\JAVA\AI-Python\AI-Python`
这是一个 Django + React 前后端分离项目,核心功能是从第三方 API驿达商业平台拉取数据并存储到本地数据库达梦/Oracle。项目包含
- **数据更新定时任务**`SCHEDULED_UPDATE_TASK` + `DATA_UPDATE_CONFIG`):按配置自动从第三方 API 拉取数据并 upsert 到本地表
- **历史数据回溯**`HISTORY_BACKFILL_CONFIG`):定期回溯检查历史月份数据是否有变动,按需同步
- **动态查询 API**`API_CONFIG`):根据配置动态生成本地数据查询接口
## 本次会话完成的工作
### 1. 修复本地数据获取 endpoint 错误 ✅
**问题**`_fetch_local_check_data` 使用 `DATA_UPDATE_CONFIG.NAME`(中文描述名如"更新python语义营收")构造 URL导致 404。
**修复**
- 修改 [history_backfill_service.py](file:///e:/workfile/JAVA/AI-Python/AI-Python/api/history_backfill_service.py) 的 `_get_data_update_config()` 方法,增加子查询 JOIN `API_CONFIG`,通过 `TARGET_TABLE = TABLE_NAME` 获取正确的 `local_endpoint`
- 修改 `_check_month_changed()` 使用 `duc_config['local_endpoint']` 替代 `duc_config['name']`
- 同步修复 [history_backfill_views.py](file:///e:/workfile/JAVA/AI-Python/AI-Python/api/history_backfill_views.py) 的 `BackfillCheckPreviewView`
### 2. 清理 DEBUG 日志 ✅
删除 [dynamic_query_service.py](file:///e:/workfile/JAVA/AI-Python/AI-Python/api/dynamic_query_service.py) 中所有 `[DEBUG]` 级别的 print 语句(约 30 处包括SQL 参数、字段匹配、汇总包裹、模糊查询等
### 3. 改进变更检测日志输出 ✅
修改 `_check_month_changed()` 的对比逻辑,无论字段匹配与否都输出日志:
```
[DETECT] 202501 | 对客销售 = 一致 | 本地=12345 | 远端=12345
[DETECT] 202501 | 年度累计 ≠ 不同 | 本地=99999 | 远端=88888
[DETECT] 202501 结论: 发现差异,需要全量同步
```
### 4. 调整超时时间 ✅
变更检测的 API 调用超时从 30 秒调整为 120 秒(与全量同步一致)。
### 5. MonthINCAnalysisProxyView 修改 ✅
将 `/api/revenue/month-inc-analysis/` 接口的 `ServerpartId` 从必填改为可选。
### 6. 修复 NEWGETSUMMARYREVENUEMONTH 展平问题(部分完成)
在 [data_processing_utils.py](file:///e:/workfile/JAVA/AI-Python/AI-Python/api/data_processing_utils.py) 的 `process_downloaded_data` 中,对 `NEWGETSUMMARYREVENUE` 和 `NEWGETSUMMARYREVENUEMONTH` 表跳过 `extract_serverpart_data` 步骤。
---
## 🚨 当前待解决问题
### 问题:变更检测与全量同步的数据粒度不匹配
**现象**:回溯执行"更新驿达看板首页数据缓存"NEWGETSUMMARYREVENUEMONTH 表)时,变更检测判定"有差异"后触发全量同步,但全量同步结果全部是"跳过"(数据一致),没有任何实际更新。
**根因分析**
| 阶段 | 调用方式 | 数据粒度 |
|---|---|---|
| 变更检测(本地) | `GET /api/dynamic/ahydDIBData/?StatisticsStartMonth=202501&StatisticsEndMonth=202501`(不传 ServerpartId | **省级汇总**123 条聚合成 1 条) |
| 变更检测(远端) | `GET GetSummaryRevenueMonth?pushProvinceCode=340000&StatisticsMonth=202501`(不传 ServerpartId | **省级汇总**(需确认返回结构) |
| 全量同步 | `execute_update_internal` → 按 133 个 ServerpartId 逐个调用第三方 API | **服务区级**(每次 1 条) |
**变更检测的两个子问题**
1. **远端值为 None**:之前字段路径配置错误(用 `CashPay` 而非 `MonthRevenueModel.CashPay`),用户已手动修正为嵌套路径
2. **数据口径不一致**:本地汇总是 dynamic API 的聚合计算结果,远端是第三方 API 不传 ServerpartId 时的返回值,两者可能不是同一个统计口径
**全量同步"跳过123"**
- `execute_update_internal` 调用 `process_downloaded_data` 处理数据
- upsert 按 `STATISTICS_MONTH + SERVERPART_ID` 匹配后,逐字段比对发现数据与数据库完全一致
- 这说明数据确实没变化,跳过是正确行为
- 但如果变更检测一直误判为"有差异",就会每次执行无效的全量同步(浪费资源)
---
## 关键文件说明
| 文件 | 用途 |
|---|---|
| `api/history_backfill_service.py` | 回溯服务核心:调度、变更检测、执行全量同步 |
| `api/history_backfill_views.py` | 回溯 API 视图CRUD、手动触发、检测预览 |
| `api/data_update_internal.py` | 定时任务内部执行函数(被回溯服务调用) |
| `api/data_update_views.py` | 数据更新视图(手动执行入口,有完整的行内特殊处理) |
| `api/data_processing_utils.py` | 数据处理工具展平、提取、upsert |
| `api/dynamic_query_service.py` | 动态查询服务(本地数据 API |
| `api/revenue_proxy_views.py` | 第三方 API 代理视图 |
| `frontend/src/components/BackfillConfigPage.tsx` | 回溯配置前端页面 |
## 数据库表关系
```
SCHEDULED_UPDATE_TASK (定时任务)
├── CONFIG_ID → DATA_UPDATE_CONFIG (数据源配置API URL、目标表、参数映射)
└── HISTORY_BACKFILL_CONFIG (回溯配置TASK_ID → 关联任务)
DATA_UPDATE_CONFIG.TARGET_TABLE = API_CONFIG.TABLE_NAME (1:1 或 1:N 映射)
API_CONFIG.ENDPOINT → 动态查询 API 的 endpoint 名
```
## 后续建议
1. **修正变更检测逻辑**:要么让变更检测也按服务区级别对比(但太慢),要么确认不传 ServerpartId 时第三方 API 返回的省级汇总字段路径完全正确
2. **考虑方案 B**:变更检测直接查数据库比对,绕过 HTTP 调用,避免数据结构适配问题
3. **注意 `data_update_views.py` vs `process_downloaded_data` 的差异**:前者有更完善的行内特殊处理(字段优先级保护、智能唯一键补充),后者是简化版。当前回溯使用后者