Python 数据校验:Great Expectations 不是写几条规则就完事
Python 数据校验:Great Expectations 不是写几条规则就完事
数据质量工具很容易被当成“规则配置器”:某列不能为空,某个字段在枚举范围内,某个数值大于 0。Great Expectations 这类工具确实能帮我们写规则,但数据校验真正难的是规则维护、告警处理、业务解释和质量闭环。写几条 expectation 只是开始。
数据校验要从“发现问题”走到“推动修复”。
一、规则要和业务风险绑定
flowchart TD
A[Data Rule] --> B[Business Risk]
B --> C[Severity]
C --> D[Alert]
D --> E[Owner]
不是所有规则失败都同样严重。用户 ID 为空可能直接阻断报表,昵称为空可能影响不大;订单金额为负可能是退款,也可能是异常。规则要绑定业务风险和严重级别,告警才不会变成噪音。
每条规则最好有负责人。规则失败后谁处理、处理时限多久、是否阻断下游任务,都要明确。没有 owner 的数据质量告警,最后通常没人管。
为什么数据校验规则必须绑定"业务风险等级"而非仅仅"技术严重性"? 因为技术视角的"严重"和业务视角的"严重"经常是颠倒的。技术上,
order_id为 NULL 只是一个NotNull规则失败;业务上,这 50 条订单无法关联支付信息,意味着 50 个用户的 GMV 会丢失,影响月报汇总。反过来,技术上user_nickname缺失是字段不完整,业务上这只是一个展示优化问题,不影响任何决策。如果没有把规则映射到业务风险等级,告警系统的优先级排序会失效——你的钉钉群里每周 200 条告警、180 条技术严重但业务无感,老板说"关了告警吧反正吵死了"。规则的 Severity 定义不是给工程师看的,是给"要不要半夜爬起来修"做决策用的。
二、Expectation 要可读
validator.expect_column_values_to_not_be_null("order_id")
validator.expect_column_values_to_be_between("pay_amount", min_value=0)
规则命名和说明要让业务也能理解。不要只保留技术字段名,可以补充中文描述、业务口径和失败示例。数据质量不是数据工程师自嗨,最终要让使用数据的人知道风险在哪里。
对于复杂规则,可以拆成多个简单规则。比如“有效订单”可能涉及状态、金额、支付时间、渠道等字段。拆开后更容易定位失败原因,也更容易解释给业务方。
三、校验结果要进入调度
quality_gate:
table: dws_order_daily
block_if:
- critical_failed
warn_if:
- warning_failed
数据校验如果只生成一份报告,很多时候没人看。关键表应该把校验结果接入调度系统:严重失败阻断下游,轻微失败发出告警但允许继续。这样质量规则才真正影响数据链路。
阻断要谨慎。阻断核心任务可能影响报表刷新,也可能保护业务不看错数。哪些规则能阻断,必须经过业务和数据团队共同确认。不能所有失败都阻断,也不能所有失败都放行。
四、质量趋势比单次结果更有用
SELECT rule_name, dt, failed_count
FROM data_quality_result
WHERE table_name = 'dws_order_daily';
单次规则失败告诉我们今天有问题,质量趋势告诉我们问题是不是长期存在。某个字段缺失率缓慢上升,比一次偶发失败更值得关注。看趋势能发现数据链路正在变坏。
质量结果也可以进入数据资产页面。使用某张表的人能看到最近 30 天质量评分、失败规则和负责人,就会更清楚这张表是否可靠。数据可信度应该对使用者可见。
规则本身也要版本化。今天新增规则导致质量分下降,不代表数据突然变差;可能只是我们开始检查以前没检查的问题。把规则版本和数据结果一起保存,才能正确解释质量趋势。
告警文案也要写清楚。不要只发"规则失败",而要告诉负责人哪张表、哪个分区、哪条规则、失败数量、影响下游和建议动作。数据质量告警越像任务,越容易被处理;越像噪音,越容易被静音。
为什么质量趋势比单次校验结果更有价值? 因为单次规则失败可能是偶发——网络抖动导致某批次数据延迟入库、ETL 任务临时超时——修复后第二天就恢复了。但趋势型恶化是"温水煮青蛙"式的:某个字段的缺失率从 0.5% 每周上升 0.3%,3 个月后变成了 4%,这期间没有任何一天触发告警阈值(因为你设的阈值是 5%),但数据质量已经在持续变差。如果不看趋势只看单天对比,你永远发现不了这个问题。质量趋势的本质是把"静态阈值"升级为"动态预警"——你不是在等一条规则被打破,而是在监测数据质量是否在走向恶化。
🚨 踩坑提醒
- Great Expectations 的
expect_column_values_to_be_between在边界值上可能不符合预期 — 默认的min_value和max_value是闭区间还是开区间,要明确验证。如果订单金额边界设为 [0, 100000],恰好金额为 100000 的订单会被判定为 PASS 还是 FAIL?不同版本的 GE 行为可能不一致。 - 规则版本化了但质量分数变了,别急着说数据坏了 — 如果你新增了 10 条规则(之前没检查),质量分数从 95 分跌到 72 分,这不是数据出了问题,而是"之前没检查的问题被暴露出来了"。质量报告里必须把"规则变更带来的分数变化"和"数据本身变差带来的分数变化"区分开,否则运营会误判。
quality_gate阻断太激进会阻塞整条数据链路 — 设了block_if: critical_failed之后,一旦 ODS 层的某个字段空值率超标,DWS/ADS 层的所有 ETL 都不会跑,看板全部停更。阻断策略要分表执行:核心交易表可以阻断,日志接入表建议只告警不阻断。
五、总结
Python 数据校验和 Great Expectations 的价值,不只是写规则,而是把规则和业务风险、负责人、调度阻断、告警和质量趋势连接起来。
数据质量不是一张绿色报告。它是一套让问题被发现、被理解、被修复的机制。
更多推荐
所有评论(0)