3.0 KiB
Raw Blame History

phase, plan, wave, title, depends_on, files_modified, autonomous, requirements
phase plan wave title depends_on files_modified autonomous requirements
5 1 1 30 天窗口去重修复DATA-01
app/services/ingest/dedup.py
tests/ingest/test_dedup.py
true
DATA-01

Phase 5 Plan 01: 30 天窗口去重修复DATA-01

Objective

dedup.pybatch_dedup_filter() 目前查全量历史数据去重,导致同一职位超过 30 天后无法重新入库。 本 Plan 在去重查询 SQL 中加入 30 天时间窗口。

Must Haves

  • 单字段 dedup SQL 加 AND created_at > now() - INTERVAL 30 DAY
  • 双字段 dedup SQL 同样加 30 天窗口
  • 新增 Mock 测试(用 AsyncMock 模拟 ClickHouse 客户端)覆盖:
    • 30 天内有记录 → 视为重复,过滤
    • 30 天外有记录 → 不重复,允许入库
    • 无记录 → 允许入库
  • pipenv run python -m pytest tests/ingest/test_dedup.py -v 全部通过
  • 全量回归 pytest tests/ -v 无失败

Wave 1

Task 1.1: 修改 dedup.py

<read_first>

  • app/services/ingest/dedup.py(当前 81 行) </read_first>
修改 `batch_dedup_filter()` 中的两个 SQL 查询:

单字段去重(第 51 行附近):

# 修改前
query = f"SELECT {key_col} FROM {table} WHERE {key_col} IN {{keys:Array(String)}}"

# 修改后
query = (
    f"SELECT {key_col} FROM {table} "
    f"WHERE {key_col} IN {{keys:Array(String)}} "
    f"AND created_at > now() - INTERVAL 30 DAY"
)

双字段去重(第 65 行附近):

# 修改前
query = f"SELECT {c1}, {c2} FROM {table} WHERE {c1} IN {{keys:Array(String)}}"

# 修改后
query = (
    f"SELECT {c1}, {c2} FROM {table} "
    f"WHERE {c1} IN {{keys:Array(String)}} "
    f"AND created_at > now() - INTERVAL 30 DAY"
)

<acceptance_criteria>

  • grep "INTERVAL 30 DAY" app/services/ingest/dedup.py 有两处输出
  • grep "INTERVAL 30 DAY" app/services/ingest/dedup.py | wc -l 输出为 2 </acceptance_criteria>

Task 1.2: 新增 Mock 测试

创建 `tests/ingest/__init__.py`(空文件)和 `tests/ingest/test_dedup.py`

测试覆盖:

  1. test_single_field_dedup_within_30_days30 天内有相同 job_id → 过滤duplicate=1
  2. test_single_field_dedup_outside_30_days:先不存在 → 允许入库duplicate=0模拟 30 天外无记录)
  3. test_double_field_dedup_within_30_days:双字段在 30 天内有记录 → 过滤
  4. test_dedup_empty_input:空输入 → 直接返回,不查 ClickHouse
  5. test_dedup_no_dedup_columns:无 dedup 字段 → 跳过过滤
  6. test_build_insert_row_has_channel:验证 build_insert_row 生成的行包含 channel 列

SQL 验证:用 mock_client.query.call_args[0][0] 断言 SQL 中包含 INTERVAL 30 DAY


Verification

# 1. 验证 SQL 变更
grep "INTERVAL 30 DAY" app/services/ingest/dedup.py
# 预期输出2 行

# 2. 运行新增测试
pipenv run python -m pytest tests/ingest/test_dedup.py -v

# 3. 全量回归
pipenv run python -m pytest tests/ -v --tb=short