Files
feiqiu-ETL/tmp/test_conflict_modes.py
2026-02-04 21:39:01 +08:00

71 lines
2.1 KiB
Python

# -*- coding: utf-8 -*-
"""
测试 ODS 冲突处理三种模式
"""
print("=" * 70)
print("ODS 冲突处理模式说明")
print("=" * 70)
modes = [
("nothing", "跳过已存在记录", """
INSERT INTO table (...) VALUES (...)
ON CONFLICT (pk) DO NOTHING
行为: 已存在的记录完全跳过,不做任何更新
适用: 严格保留原始快照,不允许修改历史数据
"""),
("backfill", "回填 NULL 列", """
INSERT INTO table (...) VALUES (...)
ON CONFLICT (pk) DO UPDATE SET
col1 = COALESCE(table.col1, EXCLUDED.col1),
col2 = COALESCE(table.col2, EXCLUDED.col2)
WHERE table.col1 IS NULL OR table.col2 IS NULL
行为: 只填充数据库中为 NULL 的字段,已有值保持不变
适用: 新增字段后回填历史数据,但不覆盖已有值
"""),
("update", "全字段对比更新 (默认)", """
INSERT INTO table (...) VALUES (...)
ON CONFLICT (pk) DO UPDATE SET
col1 = EXCLUDED.col1,
col2 = EXCLUDED.col2
WHERE table.col1 IS DISTINCT FROM EXCLUDED.col1
OR table.col2 IS DISTINCT FROM EXCLUDED.col2
行为: 对比所有字段,有变化则更新
适用: 数据同步,保持与 API 一致
"""),
]
for mode, title, sql in modes:
print(f"\n【模式: {mode}{title}")
print("-" * 50)
print(sql)
print("=" * 70)
print("配置方式 (在 .env 中设置)")
print("=" * 70)
print("""
# 方式1: 直接设置模式
run.ods_conflict_mode=update # 全字段对比更新 (默认)
run.ods_conflict_mode=backfill # 只回填 NULL
run.ods_conflict_mode=nothing # 跳过已存在
# 方式2: 兼容旧配置
run.ods_backfill_null_columns=false # 等同于 nothing 模式
""")
print("=" * 70)
print("对比表")
print("=" * 70)
print("""
| 场景 | nothing | backfill | update |
|--------------------------|---------|----------|--------|
| 新记录 | 插入 | 插入 | 插入 |
| 已存在 + 字段已有值 | 跳过 | 保留原值 | 更新 |
| 已存在 + 字段为 NULL | 跳过 | 填充新值 | 填充 |
| 已存在 + API值与DB相同 | 跳过 | 跳过 | 跳过 |
""")