ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Great Expectations数据质量框架实战:从校验规则到ETL自动化拦截

Great Expectations数据质量框架实战:从校验规则到ETL自动化拦截 上个月处理一个数据异常折腾了大半天最后定位到根因的时候挺无语每天凌晨的数据清洗任务跑完是绿的接口也没报错但有一批订单金额字段写成了负值。你说它多不至于让下游服务直接挂掉可它偏偏能把当天的毛利汇总带偏好几个点等到业务同学发现已经晚了。这种场景做数据的人应该都不陌生——数据管道跑完只会告诉你“成功”还是“失败”没人告诉你“数据本身对不对”。Great Expectations下面统称 GX就是用来补这块短板的开源数据质量框架。它把校验写成了代码用声明式的规则告诉数据管道订单号不能为空、金额必须在 0 到 10000 之间、状态字段只能是枚举里的那几种值。校验不通过就直接让任务失败或者把结果推给负责人而不是让脏数据默默流进报表和下游系统。很多团队拿它当“数据测试框架”用跟写代码要写单元测试一个道理数据也需要测试。这篇教程我不会照搬官方文档只讲我实际用下来的经验从概念拆解到跑通第一条规则再到把校验接入日常调度以及那些文档里不会告诉你的坑一次说清楚。1. 先搞清楚 GX 到底解决什么问题1.1 数据管道里的“单元测试”写后端代码的时候没人会不写单元测试就上线对不对断言、mock、边界条件该覆盖的都覆盖一遍。但到了数据人生成的时候很多团队反而很随意写个 SQL 清洗一下定时跑起来只要不报错就当它没问题。可数据会变上游系统的字段可能改格式某个接口某天突然返回了全 null 的列表甚至数据库表结构变了但没人同步。这些变化很多时候并不会让任务直接失败而是静默污染结果。GX 做的事情就是给数据加上断言。你可以把一条条校验规则理解成单元测试的 assert只不过断言的对象从变量变成了 DataFrame、SQL 查询结果、或者 Spark 表。数据通过校验任务继续数据不通过任务按你预设的方式失败、告警或者分流。1.2 该用 GX 去管哪些事用下来下面几类场景非常适合 GX新数据源接入第一次接到第三方或业务库的数据先跑一遍完整性、格式、值域检查比啥都不管就接进数仓稳妥得多。数据迁移前后对比表结构升级、切库、换存储在迁移前后各跑一遍相同套件的校验能快速发现迁移带来的数据偏差。每日批处理后的质量闸门任务写完表以后先跑质量检查再供下游读取质检不过就阻塞。模型训练前的数据体检喂给模型之前先验证特征列的空值率、取值分布、数据漂移指标。1.3 别指望 GX 做所有事有一点需要明确GX 不是实时流处理引擎也不是数据监控系统。虽然它也能定时跑校验但真正做秒级实时监控、告警聚合、指标趋势追踪还得靠专用监控平台。GX 更像是“在数据流转的关键节点上给数据设几道卡口”适合和调度系统配合使用而不是替代监控系统。2. 核心概念一次性把 GX 的术语搞懂GX 的术语体系其实并不复杂但官方文档一开始就抛出一堆名词很容易劝退新人。我把最核心的几个概念从底往上拆给你看。2.1 Expectation 是这个框架的最小单位一条 Expectation 就是一条数据质量规则比如“某列不能有 null”“某列的值必须大于 0”“某列的取值必须来自某个集合”。它看起来是一条配置声明但内部封装了校验逻辑、成功与否的判断方式。我举个例子最常用的一条规则写成伪代码是expect_column_values_to_not_be_null(columnorder_id)意思简单order_id这一列不能有空值。GX 内置了几十种常用 Expectation覆盖空值、唯一性、值域、类型、分布、跨列比较、表级统计等场景基本不用自己造轮子。后面章节我会给出一个高频清单。2.2 Expectation Suite 把多条规则打包单条规则只能看一个点实际业务中你需要的是组合拳。把一组针对同一张表或同一批数据的 Expectation 打包在一起就是 Expectation Suite可以理解成一张表的“质检项目清单”。比如订单表的套件会包含主键列无空值主键列值唯一金额列在 0 到 10000 之间状态列取值属于[paid, pending, failed]表行数不小于 1000Suite 是 GX 中非常核心的复用单位。你可以在测试环境先定义好套件再拿到生产环境用同一个套件去校验保证两边口径完全一致。2.3 Data Context 是你所有配置的总入口Data Context 是 GX 项目的中枢对象它负责管理数据源、套件、Checkpoint、验证结果和报告文档。在新版本里几乎每一步操作都要从context出发。代码里你会经常看到这样的开头import great_expectations as gx context gx.get_context()这一行执行完GX 会在当前目录下生成一个great_expectations/目录里面存放项目配置、数据源定义、套件和验证结果。这个目录建议纳入版本管理整个团队共用一套配置。2.4 Checkpoint 让校验可以自动执行规则定义好了总得有个入口去执行。Checkpoint 就是 GX 的执行单元它把“数据源 一个或多个 Suite”绑定在一起一次触发、批量校验。你可以为每一张关键表配置一个 Checkpoint也可以在同一个 Checkpoint 里放多张表。Checkpoint 执行完会产生 Validation Result这是每次校验的详细结果包括哪些规则通过、哪些不通过、期望值和实际值差多少。这个结果既会存到本地 JSON 文件也可以被代码直接读取用来自动化决策。2.5 Data Docs 自动生成可视化报告校验结果光有 JSON 还不够直观GX 会基于结果自动渲染一套静态 HTML 文档叫 Data Docs。在 Data Docs 里每张表、每个套件、每次校验的状态、成功率和详细规则结果都以报表形式呈现。这意味着团队里不懂代码的人也能直接打开网页查看数据质量现状。这一点我实际用下来觉得特别值钱数据团队跟业务团队对质量的时候直接甩一个 Data Docs 链接比截一堆日志强多了。3. 实战从安装到跑通第一条校验规则讲完概念直接上手。下面我以 GX 当前主流 API 为例带你从零跑通一个完整的校验流程。3.1 安装与环境准备安装 GX 非常简单用 pip 直接装pip install great_expectations great_expectations.data_context装完可以先看版本import great_expectations as gx print(gx.__version__)注意GX 这几年 API 变化比较大如果你用的是 0.x 老版本很多写法跟新版不一样。我这里统一用 1.x 的 API 演示。老版本怎么对照后面第 6 章会专门讲。建议你在虚拟环境里安装GX 依赖了 pandas、numpy、sqlalchemy 等一堆常用库隔离环境能少很多麻烦。3.2 初始化 Data Context 并连接第一个数据源在项目目录下执行context gx.get_context()运行后当前目录下会出现great_expectations/文件夹里面有great_expectations.yml主配置文件和存放各类内容的子目录。GX 的配置体系也支持直接往目录里丢 YAML 文件操作方式很工程化。然后连接数据源。最简单的演示方式是用 pandas 的 DataFrame 当数据源几乎所有 Python 数据开发都熟悉这个import pandas as pd df pd.DataFrame({ order_id: [1001, 1002, 1003, 1004, 1005], amount: [99.9, 150.0, 200.5, 45.0, 300.0], status: [paid, paid, pending, paid, failed] }) datasource context.sources.add_pandas(order_datasource) asset datasource.add_dataframe_asset(order_asset) batch asset.get_batch(dataframedf)这里order_datasource是数据源的名字order_asset是数据资产的标识。以后每次要校验新传入的 DataFrame都可以通过同一个 asset 拿到一个 batchGX 的校验单位就是 batch——一批数据。3.3 写第一条 Expectation 并查看校验结果数据和 context 都准备好了直接校验result batch.validate( gx.expectations.ExpectColumnValuesToNotBeNull(columnorder_id) ) print(result.success)result.success是布尔值True 表示校验通过False 表示有数据不满足条件。我故意把订单表造得干干净净所以这里会输出 True。再看一眼完整结果结构print(result.result)返回的字典里包含element_count、unexpected_count、unexpected_list等字段。unexpected_list非常有用它会直接列出哪些值不满足规则。比如把 status 列里塞进一个空值再跑一次就能在unexpected_list里看到这一行数据排查效率直接拉满。4. 常用 Expectation 清单与规则设计思路实际项目里绝大多数需求都能靠内置 Expectation 覆盖。我把高频用到的规则按层级整理一份清单方便你照着选。4.1 字段级规则空值、唯一性、类型与值域字段级别用得最多基本覆盖了单列数据的质量检查需求。下面这几个是最常见的Expectation 名称作用典型场景expect_column_values_to_not_be_null列不允许有空值主键、业务关键字段expect_column_values_to_be_unique列值必须唯一订单号、用户 IDexpect_column_values_to_be_between列值必须在指定范围金额、年龄、数量expect_column_values_to_be_in_set列值必须属于某个集合状态、枚举字段expect_column_values_to_match_regex列值必须匹配正则手机号、邮箱格式expect_column_values_to_be_of_type列值类型必须一致字符串、整数、浮点设计规则的时候我有两个建议。第一不要一上来堆几十条规则从最影响业务的字段开始比如主键、金额、状态先把系统跑通再加。第二值域范围不是拍脑袋定的最好先用 profiling 方式跑一下历史数据分布再根据业务合理范围设置 boundary否则很容易误报。4.2 跨列与表级规则有些质量问题是单列看不出来的比如两列之间的逻辑关系。# 创建时间不能晚于完成时间 expect_column_pair_values_a_to_be_greater_than_b( column_Acomplete_time, column_Bcreate_time, )这种断言在数据清洗环节非常实用。表级规则里最常用的是span_expect_table_row_count_to_be_between(min_value1000, max_value50000)行数波动也是数据质量的直接信号。如果某天表行数从两万掉到五千就算每一行数据看起来都正常这条表大概率还是有问题。把行数范围写进套件能拦截很多数据管道截断、去重逻辑写错的低级失误。5. 把 ETL 流程接上自动化质检单次校验能跑通只是第一步生产环境里真正需要的是让数据任务每天自动跑质量检查失败就拦住下游。这就得靠 Checkpoint。5.1 持久化 Expectations 和 Checkpoint我建议把的搞法不是每次临时造 Expectation而是先通过context持久化定义一个 Suite再在 Checkpoint 里引用它。新建一个套件suite context.suites.add( gx.ExpectationSuite(nameorder_suite) )然后往套件里加几条规则加完再持久化。只要你跑过context.suites.add(...)GX 就会把套件保存到本地great_expectations/suites/目录。定义 Checkpoint 也比较直接把数据源、batch 和 suite 绑定起来checkpoint context.checkpoints.add( gx.Checkpoint( nameorder_daily_checkpoint, validation_definitions[ gx.ValidationDefinition( databatch, suitesuite, nameorder_validation, ) ], ) )Checkpoint 存下来之后以后每次要跑质检一行代码就行checkpoint.run()本地项目里great_expectations/checkpoints/下会生成对应的 YAML 配置也可以手工维护这个 YAML但新手建议用代码定义报错信息更友好。5.2 让校验结果进入决策流校验结果不能每次跑完就看一眼得让他自动化处理。run()返回的结果对象里带success属性可以直接用来做任务级决策result checkpoint.run() if not result.success: # 发送告警、钉钉机器人、飞书机器人等 send_alert(今日订单表质量校验未通过请及时排查) raise RuntimeError(数据质量校验未通过)我见过不少团队把 GX 直接嵌进调度脚本里校验不通过就抛异常让 Airflow 或 DolphinScheduler 把任务标记为失败。这种设计非常直接有效数据质量具备了拦截能力。5.3 接入定时调度GX 本身不负责定时执行它需要和你的调度平台配合。你可以封装一个 Python 脚本把上面那套逻辑放进去然后用 crontab、Airflow、DolphinScheduler、甚至 CI/CD 里的定时任务去触发。一个小建议如果在 Airflow 里用把 GX 校验封装成独立的 PythonOperator 或自定义插件不要和 ETL 算子写在一个大函数里。这样调度依赖关系清晰哪一步挂了看 DAG 图一目了然。6. 实战中踩过的坑与排查技巧6.1 新老 API 混用是重灾区GX 的 API 演进过好几次。老版本里入口是great_expectations as ge用ge.get_context()新版本入口是gx.get_context()。代码层面很多 Expectation 的写法也变了老版本的validator.expect_column_values_to_not_be_null(column...)这种调用方式在新版本的某些路径下变得不推荐取而代之的是把 Expectation 作为对象传入。如果你在网上搜教程很容易看到一堆混着写的代码复制下来直接跑大概率会报错。踩过这个坑之后我的经验是先搞清楚自己装的是哪个大版本再去对应版本的官方文档查 API别拿老教程硬套新版本。遇到报错先看版本再查日志。为了方便对照我把最关键的一处差异列出来功能老版 0.x/1.x 早期新版 1.x 推荐写法入口导入import great_expectations as geimport great_expectations as gx获取上下文ge.get_context()gx.get_context()数据源创建context.sources.add_pandascontext.sources.add_pandas期望规则validator.expect_column_values_to_not_be_null(col)gx.expectations.ExpectColumnValuesToNotBeNull(columncol)这个表格看着简单但哪怕是我刚开始从老 API 迁移到新 API 的时候也踩了好几回坑。我的建议是新项目别犹豫直接用新版 API长痛不如短痛。6.2 大表校验的性能问题默认情况下 GX 会把整张表的全部数据拉进内存做校验这在几百万行以内问题不大但到了亿级表就会非常吃力。处理大表我有三个实际经验第一能抽样就抽样很多质检目标根本不需要全量数据。GX 的 batch 支持batch_spec里的采样参数或者直接传入一个已经抽样过的 DataFrame。第二能分区就分区按日期分区取最新分区校验或者按业务维度拆成多个小 batch避免一次加载全部数据。第三对于超大表优先走 SQL 或 Spark 数据源。GX 会把部分 Expectation 下推到 SQL 引擎或 Spark executor 里去执行而不是把数据全部拉回客户端性能完全不是一个量级。6.3 误报和漏报的平衡规则设得太松脏数据溜过去设得太严天天误报告警团队疲了就不看了。这个平衡点没有标准答案但我建议先跑几天 profiling看看历史质量情况再定合理边界。profiling 是 GX 内置的探索性工具可以对数据集自动生成一批建议的规则和阈值用作参考起点。另外一个容易被忽略的点不同批次的数据量级可能有差异比如大促期间单量暴涨如果你把行数上限设得太死校验就会误报。这时候最好给行数规则留弹性或者根据业务日历动态调整阈值。6.4 团队协作时的配置管理GX 的项目配置是本地文件天然适合纳入 Git 管理。但我见过不少团队各人本地初始化出不同的great_expectations.yml互相覆盖最终弄得乌烟瘴气。我建议从一开始就把great_expectations/目录纳入代码仓库并且约定好数据源定义统一放共享环境个人只在分支上改。Data Docs 的静态页面可以配置统一存储或者让 CI 自动渲染后发布到内部 Web这样全团队看到一个最新的数据质量报告。7. 进阶玩法把 GX 用得更顺手如果你已经把基础流程跑通了下面几个方向值得继续深挖。第一个是自定义 Expectation。内置规则覆盖了大多数场景但总有一些业务校验是框架没有的比如“连续七天订单金额标准差不能超过某个值”。GX 支持你自定义 Expectation自己写校验逻辑、渲染结果。这个能力让你能把领域经验沉淀成通用断言后续团队其他人直接复用。第二个是把 Data Docs 接入 CI/CD。每次 MR 涉及数据模型变更时自动触发一轮 GX 校验用测试数据跑一遍相关 Suite把结果作为合并的前置条件。这就像代码的持续集成一样数据模型变更也具备持续验证能力。第三个是跟血缘元数据结合。GX 的 Checkpoint 命名和数据资产命名可以跟你的元数据系统打通自动把质量卡片绑定到对应的数据资产页面上。业务同学点开一个表就能直接看到这张表最近一周的质量状态价值非常大尤其适合数据平台团队自建数据门户的场景。我个人在实际操作中的体会是GX 的学习曲线不在于概念多难而在于“先亲眼看着一条规则跑通再延伸到全链路”这个过程。很多人一开始就想着把所有表都接进去、所有规则都配齐结果配置量太大没法维护最后不了了之。更好的起点是挑一张最核心的业务表先让一条最关键的规则在调度里跑起来稳定运营一两周之后再慢慢加规则、加表。数据质量这事宁可细水长流不要一锤子买卖。
返回列表