GE 生态全景:从 Expectation 到 Suite 再到 Checkpoint 的完整数据质量链路

数据质量这件事,说起来简单——就是数据对不对、全不全、准不准。但真要在生产环境里落地,你会发现它其实是一整套链路。Great Expectations 把这套链路抽象成了三个核心概念:Expectation、Suite、Checkpoint。我刚开始用 GE 的时候,也花了不少时间才理清它们之间的关系。

说白了,这三个东西就是层层递进的:Expectation 是单个规则,Suite 是一组规则的集合,Checkpoint 则是把规则跑起来并输出结果的执行单元。今天我们就从最底层开始,一步步往上拆。

核心理解:Expectation 定义「数据应该长什么样」,Suite 组织「哪些规则一起验证」,Checkpoint 负责「在什么时候、用什么方式去验证」。这三层缺一不可。

1.1 Expectation:数据质量的最小单元

Expectation 是什么?就是一条具体的、可执行的断言。比如「这个字段不能为空」「这个列的值必须在 0 到 100 之间」「这张表的行数应该大于 1000」。每条 Expectation 都包含一个期望类型和对应的参数。

GE 内置了上百种 Expectation,覆盖了常见的数据质量场景。我列几个常用的给你看看:

Expectation 类型 作用 典型场景
expect_column_values_to_not_be_null 检查字段是否为空 主键字段、必填字段
expect_column_values_to_be_between 检查数值范围 年龄、金额、评分
expect_column_values_to_be_in_set 检查值是否在枚举列表中 状态码、类别字段
expect_table_row_count_to_be_between 检查表行数 数据量监控、增量校验
expect_column_distinct_values_to_be_in_set 检查去重后的值集合 维度表值域校验

每条 Expectation 在 GE 里其实就是一个 Python 类。你可以直接调用,也可以自定义。举个例子:

import great_expectations as ge

# 创建一个简单的 Expectation
df = ge.read_csv("sales_data.csv")
df.expect_column_values_to_not_be_null("order_id")
df.expect_column_values_to_be_between("amount", min_value=0, max_value=10000)
df.expect_table_row_count_to_be_between(min_value=100, max_value=5000)

嗯,这里要注意:Expectation 本身只是定义规则,它不会自动执行。你需要把它放到一个上下文里才能跑起来。这个上下文就是 Suite。

我的习惯:在写 Expectation 的时候,我会先想清楚「这条规则失败意味着什么」。是数据源有问题?还是 ETL 逻辑有 bug?还是业务规则变了?想清楚这个,你才知道该用哪种 Expectation。

1.2 Expectation Suite:规则的集合与组织

一条 Expectation 只能检查一个点。但实际的数据质量场景,往往需要同时检查几十甚至上百条规则。这时候就需要 Suite 出场了。

Expectation Suite 就是一组 Expectation 的集合。你可以把它理解成一个「检查清单」。比如针对订单表,我可能会定义一个 Suite,里面包含:

  • 订单 ID 不能为空
  • 订单金额在 0 到 10000 之间
  • 订单状态只能是 'pending'、'paid'、'shipped'、'cancelled'
  • 创建时间不能晚于当前时间
  • 用户 ID 必须在用户表中存在

Suite 的好处是:你可以把规则按业务场景分组,然后复用。比如「核心表校验 Suite」「增量数据校验 Suite」「月度对账 Suite」等等。

创建 Suite 有两种方式:

  1. 手动定义:用 Python 代码逐条添加 Expectation
  2. 自动生成:用 GE 的 Profiler 工具,自动扫描数据并生成建议的 Expectation

我个人更推荐先自动生成,再手动调整。因为 Profiler 能帮你发现一些你没想到的规则,比如某个字段的取值分布、空值比例等。我曾经在一个项目中,用 Profiler 自动扫描了一张 200 个字段的表,生成了 300 多条 Expectation,然后我手动筛选出 80 条真正有用的。省了不少时间。

import great_expectations as ge
from great_expectations.dataset import PandasDataset

# 创建 Suite
suite = ge.core.ExpectationSuite("order_suite")

# 添加 Expectation
suite.add_expectation(
    ge.core.ExpectationConfiguration(
        expectation_type="expect_column_values_to_not_be_null",
        kwargs={"column": "order_id"}
    )
)
suite.add_expectation(
    ge.core.ExpectationConfiguration(
        expectation_type="expect_column_values_to_be_between",
        kwargs={"column": "amount", "min_value": 0, "max_value": 10000}
    )
)

避坑指南:我曾经犯过一个错误——把所有的 Expectation 都塞进一个 Suite 里。结果跑一次校验要 20 分钟,而且失败的时候很难定位问题。后来我把 Suite 按数据源和校验频率拆分成多个小 Suite,每个只包含 10-20 条规则。这样既快又好排查。

1.3 Checkpoint:把规则跑起来

有了 Expectation 和 Suite,你只是定义好了规则。但规则不跑起来,就是一堆代码。Checkpoint 就是那个「跑起来」的东西。

Checkpoint 是 GE 的执行引擎。它负责:

  • 加载数据源(数据库、文件、数据湖等)
  • 应用指定的 Suite
  • 执行校验
  • 生成校验结果
  • 输出数据文档(Data Docs)
  • 触发后续动作(告警、通知、数据阻断等)

你可以把 Checkpoint 理解成一个「配置好的作业」。它告诉 GE:用哪个数据源、用哪个 Suite、结果输出到哪里、失败了怎么办。

一个典型的 Checkpoint 配置长这样:

checkpoint_config = {
    "name": "order_checkpoint",
    "config_version": 1.0,
    "class_name": "SimpleCheckpoint",
    "validations": [
        {
            "batch_request": {
                "datasource_name": "my_database",
                "data_connector_name": "default_inferred_data_connector_name",
                "data_asset_name": "orders"
            },
            "expectation_suite_name": "order_suite"
        }
    ],
    "action_list": [
        {
            "name": "store_validation_result",
            "action": {"class_name": "StoreValidationResultAction"}
        },
        {
            "name": "update_data_docs",
            "action": {"class_name": "UpdateDataDocsAction"}
        },
        {
            "name": "send_slack_notification",
            "action": {
                "class_name": "SlackNotificationAction",
                "slack_webhook": "https://hooks.slack.com/..."
            }
        }
    ]
}

你想想看,这个配置里包含了什么?数据源、校验规则、结果存储、文档生成、告警通知。一条完整的链路,全在这里了。

我的建议:刚开始用 Checkpoint 的时候,别急着加太多 action。先配一个 StoreValidationResultAction 和 UpdateDataDocsAction,看看结果对不对。等链路跑通了,再加告警和阻断逻辑。否则出了问题你都不知道是校验本身的问题还是 action 的问题。

1.4 完整链路:从定义到执行到反馈

现在我们把三个概念串起来,看看完整的链路长什么样:

  1. 定义阶段:编写 Expectation,描述数据应该满足的条件
  2. 组织阶段:将 Expectation 分组到 Suite,形成校验清单
  3. 配置阶段:创建 Checkpoint,指定数据源、Suite 和执行策略
  4. 执行阶段:运行 Checkpoint,GE 自动加载数据、执行校验、生成结果
  5. 反馈阶段:结果存入存储,生成 Data Docs,触发告警或阻断

这个链路,说白了就是「定义-组织-执行-反馈」的循环。每次数据发生变化,你就跑一次 Checkpoint,看看数据质量是否达标。

下面这张图可以帮你更直观地理解整个链路:

GE 数据质量链路全景图 GE 数据质量链路全景图 Expectation 数据质量的最小单元 如:字段非空、值范围 Expectation Suite 规则的集合与组织 如:订单表校验清单 Checkpoint 执行引擎 加载数据、执行校验 执行与输出 校验结果 → Data Docs → 告警通知 结果存储 → 数据阻断 → 后续处理 数据源 数据库 / 文件 / 数据湖 Batch Request 加载 反馈循环:失败时阻断或告警 核心链路:Expectation → Suite → Checkpoint → 执行 → 反馈 每次数据变更,触发 Checkpoint,自动校验并输出结果

从这张图你可以看到,整个链路是闭环的。数据源进来,经过 Checkpoint 校验,输出结果,然后根据结果决定下一步动作——是通过、告警还是阻断。如果数据质量不达标,还可以触发重新处理或人工介入。

1.5 三个概念的关系总结

最后,我用一个表格来总结 Expectation、Suite 和 Checkpoint 的关系:

概念 类比 职责 粒度
Expectation 一条交通规则 定义单个数据质量条件 字段级 / 表级
Expectation Suite 一本交通法规 组织和管理多条规则 表级 / 业务场景级
Checkpoint 交警 + 摄像头 执行校验、输出结果、触发动作 作业级 / 流水线级

这个类比你想想看:交通规则(Expectation)单独一条没什么用,得凑成一本法规(Suite),然后得有交警和摄像头(Checkpoint)去执行,才能真正管住交通。数据质量也是一样的道理。

一句话总结:Expectation 定义「数据应该是什么样」,Suite 告诉你「哪些规则一起看」,Checkpoint 负责「什么时候、怎么去检查、检查完怎么办」。这三层架构,就是 GE 数据质量链路的全部秘密。

好了,这一章的内容就到这里。理解了这三个概念,你就掌握了 GE 的核心骨架。后面的章节,我们会在这个骨架上一层层加上血肉——自定义 Expectation、高级 Suite 管理、Checkpoint 的分布式执行等等。