Tracks
数据质量和一致性就像房屋的地基——没有坚实的基础,其上构建的一切都可能坍塌。这正是数据验证发挥重要作用的地方。数据验证帮助您确保数据准确、一致且可靠。
Great Expectations 是一款开源的数据验证工具,能够及早发现数据问题,并确保您的数据达到所需的质量标准。
在本指南中,我们将通过一个实用的端到端示例,带您使用 Great Expectations 进行数据验证,帮助您快速上手!
什么是 Great Expectations?
Great Expectations(GX)是一套开源框架,已在现代数据管道中用于管理与自动化数据验证而广受欢迎。
其基于 Python 的框架旨在帮助数据团队保证数据的质量与一致性。用户可以定义“期望”(expectations)——即描述有效数据应具有何种特征的规则或测试——以自动验证数据是否符合这些标准。
Great Expectations 的一些优势包括:
- 自动化数据验证 —— Great Expectations 将数据验证流程自动化,减少人工操作并将错误风险降至最低,确保数据持续满足预定义标准。
- 与数据管道集成 —— 它可轻松集成多种数据源与平台,包括 SQL 数据库s、云存储,以及ETL 工具,从而在管道的不同阶段执行数据验证。
- 清晰、可执行的验证结果 —— 该工具提供透明的验证结果,便于快速发现并解决数据质量问题。
- 数据文档化 —— Great Expectations 可生成详尽、易用的数据验证文档,帮助团队在质量标准上达成一致,并为后续使用提供参考。
- 可扩展性与灵活性 —— 作为开源工具,Great Expectations 具有高度可定制性,并可随您的数据验证需求扩展,灵活适配多种用例而无需高昂成本。
现在,让我们看一个端到端示例!
设置 Great Expectations
在本教程中,您将学习如何使用 GX Core(Great Expectations 的开源版本)来验证一个 Pandas DataFrame。我们将演示如何设置上下文、注册 Pandas 数据源、定义期望以及验证数据批次。
注意: 我们建议您配合DataLab 笔记本一起操作,您也可以自行创建 Python 脚本。
1. 安装 Great Expectations
先决条件
- 已安装 Python 3.9 至 3.12。
- 为避免冲突,强烈建议在虚拟环境中安装 Great Expectations(声明: 虚拟环境的设置不在本文讨论范围内)。
- 一个示例数据集。
注意: 如果使用提供的DataLab 笔记本,这些先决条件已满足,您可直接跳过。
使用以下命令通过 pip 安装 GX:
pip install great_expectations
该命令会安装核心包及所有必要的依赖。
2. 初始化数据上下文
Great Expectations 需要数据上下文来管理配置。我们使用临时(ephemeral)数据上下文以避免持久化配置。
import great_expectations as gx
# Get the Ephemeral Data Context
context = gx.get_context()
assert type(context).__name__ == "EphemeralDataContext"
创建您的首个数据验证套件
GX 已设置完成,接下来创建一个数据验证套件。
1. 连接数据源并创建数据资产
数据源用于将 Great Expectations 连接到您的数据,而数据资产则表示特定的数据子集(例如表、DataFrame 或文件)。
本例中,我们将准备连接到名为 inventory_parts_df 的 DataFrame。示例数据集在提供的 DataLab 中可用,运行 SQL 代码块后即可创建:

如果您不使用 DataLab,请自行创建带有示例数据的 DataFrame。
现在,创建您的数据源和数据资产:
# Add a Pandas Data Source
data_source = context.data_sources.add_pandas(name="inventory_parts")
# Add a Data Asset to the Data Source
data_asset = data_source.add_dataframe_asset(name="inventory_parts_asset")
2. 添加批次定义
批次定义用于标识并组织待验证的数据。此处我们添加一个覆盖整个 DataFrame 的批次定义:
# Define the Batch Definition name
batch_definition_name = "inventory_parts_batch"
# Add the Batch Definition
batch_definition = data_asset.add_batch_definition_whole_dataframe(batch_definition_name)
assert batch_definition.name == batch_definition_name
3. 获取批次
批次是与批次定义关联的一组数据。要进行验证,您需要检索批次并将其与您的 DataFrame(本例为 inventory_parts_df)关联:
# Define the Batch Parameters
batch_parameters = {"dataframe": inventory_parts_df}
# Retrieve the Batch
batch = batch_definition.get_batch(batch_parameters=batch_parameters)
4. 创建套件并定义期望
期望是用于验证数据的规则。在本例中,我们将定义以下简单期望:
- 确保
inventory_id值非空。 - 确保
part_num值唯一。
# Create an Expectation Suite
expectation_suite_name = "inventory_parts_suite"
suite = gx.ExpectationSuite(name=expectation_suite_name)
# Add Expectations
suite.add_expectation(
gx.expectations.ExpectColumnValuesToNotBeNull(column="inventory_id")
)
suite.add_expectation(
gx.expectations.ExpectColumnValuesToBeUnique(column="part_num")
)
# Add the Expectation Suite to the Context
context.suites.add(suite)
您可以在Expectation Gallery中查看所有可用的期望。我们鼓励您再添加一些!
定义期望后,GX 会输出期望套件配置:
{
"name": "inventory_parts_suite",
"id": "b2de0b69-0869-4163-8dde-6c09884483f7",
"expectations": [
{
"type": "expect_column_values_to_not_be_null",
"kwargs": {
"column": "inventory_id"
},
"meta": {},
"id": "53d6c42a-d190-412f-a113-783b706531f4"
},
{
"type": "expect_column_values_to_be_unique",
"kwargs": {
"column": "part_num"
},
"meta": {},
"id": "362a2bdc-616d-4b3a-b7f0-c73808caee78"
}
],
"meta": {
"great_expectations_version": "1.2.4"
},
"notes": null
}
该套件包含以下信息:
- 套件名称与 ID: 用于跟踪和管理套件的唯一名称(
inventory_parts_suite)与标识符。 - 期望: 每条规则包含:
- 检查类型(例如确保某列没有空值或具有唯一条目)。
- 参数,如被验证的列名。
- 元数据与每个期望的唯一 ID,便于跟踪与自定义。
- 元数据: Great Expectations 的版本信息,以确保工具兼容性。
- 备注: 可用于添加关于套件的描述性注释(可选)。
这种结构化输出既是文档,也是可复用的配置,用于验证您的数据集,使期望定义清晰、可追溯,并随时可用于将来。
5. 验证数据
最后,将批次与已定义的期望进行验证,并评估结果。
# Validate the Data Against the Suite
validation_results = batch.validate(suite)
# Evaluate the Results
print(validation_results)
运行验证后,Great Expectations 会提供一份详细报告,说明数据集是否满足已定义的期望:
{
"success": false,
"results": [
{
"success": true,
"expectation_config": {
"type": "expect_column_values_to_not_be_null",
"kwargs": {
"batch_id": "inventory_parts-inventory_parts_asset",
"column": "inventory_id"
},
"meta": {},
"id": "53d6c42a-d190-412f-a113-783b706531f4"
},
"result": {
"element_count": 580069,
"unexpected_count": 0,
"unexpected_percent": 0.0,
"partial_unexpected_list": [],
"partial_unexpected_counts": [],
"partial_unexpected_index_list": []
},
"meta": {},
"exception_info": {
"raised_exception": false,
"exception_traceback": null,
"exception_message": null
}
},
{
"success": false,
"expectation_config": {
"type": "expect_column_values_to_be_unique",
"kwargs": {
"batch_id": "inventory_parts-inventory_parts_asset",
"column": "part_num"
},
"meta": {},
"id": "362a2bdc-616d-4b3a-b7f0-c73808caee78"
},
"result": {
"element_count": 580069,
"unexpected_count": 568352,
"unexpected_percent": 97.98006788847535,
"partial_unexpected_list": [
"48379c01",
"paddle",
"11816pr0005",
"2343",
"3003",
"30176",
"3020",
"3022",
"3023",
"30357",
"3039",
"3062b",
"3068b",
"3069b",
"3069b",
"33291",
"33291",
"3795",
"3941",
"3960"
],
"missing_count": 0,
"missing_percent": 0.0,
"unexpected_percent_total": 97.98006788847535,
"unexpected_percent_nonmissing": 97.98006788847535,
"partial_unexpected_counts": [
{
"value": "3069b",
"count": 2
},
{
"value": "33291",
"count": 2
},
{
"value": "11816pr0005",
"count": 1
},
{
"value": "2343",
"count": 1
},
{
"value": "3003",
"count": 1
},
{
"value": "30176",
"count": 1
},
{
"value": "3020",
"count": 1
},
{
"value": "3022",
"count": 1
},
{
"value": "3023",
"count": 1
},
{
"value": "30357",
"count": 1
},
{
"value": "3039",
"count": 1
},
{
"value": "3062b",
"count": 1
},
{
"value": "3068b",
"count": 1
},
{
"value": "3795",
"count": 1
},
{
"value": "3941",
"count": 1
},
{
"value": "3960",
"count": 1
},
{
"value": "48379c01",
"count": 1
},
{
"value": "paddle",
"count": 1
}
],
"partial_unexpected_index_list": [
0,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21
]
},
"meta": {},
"exception_info": {
"raised_exception": false,
"exception_traceback": null,
"exception_message": null
}
}
],
"suite_name": "inventory_parts_suite",
"suite_parameters": {},
"statistics": {
"evaluated_expectations": 2,
"successful_expectations": 1,
"unsuccessful_expectations": 1,
"success_percent": 50.0
},
"meta": {
"great_expectations_version": "1.2.4",
"batch_spec": {
"batch_data": "PandasDataFrame"
},
"batch_markers": {
"ge_load_time": "20241129T122532.416424Z",
"pandas_data_fingerprint": "84a1e1939091fcf54324910def3b89cd"
},
"active_batch_definition": {
"datasource_name": "inventory_parts",
"data_connector_name": "fluent",
"data_asset_name": "inventory_parts_asset",
"batch_identifiers": {
"dataframe": "<DATAFRAME>"
}
}
},
"id": null
}
该报告详述了您的数据质量,突出展示了通过与未通过之处。以下是结果的简要说明:
整体验证:验证结果部分成功:50% 的期望通过,50% 失败。失败的期望说明存在需要关注的数据质量问题。本例中有一列未满足定义的规则。
期望 1:inventory_id 不应有缺失值
- 结果:通过
- 说明:
inventory_id列中的每个值均存在,没有空值或缺失项,表明该列具有良好的数据完整性。
期望 2:part_num 应具有唯一值
- 结果:未通过
- 说明:
part_num列包含 97.98% 的重复值,仅有少数值是唯一的。 - 要点:
- 示例重复值包括“3069b”和“33291”。
- 该工具还展示了这些重复值的出现频次与行位置,便于定位并修复问题。
当然,这只是一个示例数据集,我们特意包含了一个通过与一个未通过的期望,便于您了解两种验证结果。
就是这样!您已成功完成端到端的数据验证。
将 Great Expectations 集成到数据管道
在生产环境中,验证必须直接嵌入工作流,以在各个阶段持续监控数据质量。
本节将讨论如何将 Great Expectations 集成到您的数据管道中。
以下示例旨在提供思路,可能需要本文未包含的额外配置。请查看各工具文档以获取最新语法!
与 ETL 工具集成
将 Great Expectations 与常见的 ETL 工具(如 Apache Airflow 或 Prefect)集成相对简单。将验证步骤直接嵌入 ETL 流程,可在影响下游分析之前实时捕获并处理数据问题。
下面演示一个将 Great Expectations 集成到 Prefect 的简单示例,以在自动化 ETL 工作流中运行数据验证:
from prefect import task, Flow
import great_expectations as ge
# Define a task to run Great Expectations validation
@task
def validate_data():
context = ge.data_context.DataContext()
batch_kwargs = {"path": "path/to/your/datafile.csv", "datasource": "your_datasource"}
batch = context.get_batch(batch_kwargs, suite_name="your_expectation_suite")
results = context.run_validation_operator("action_list_operator", assets_to_validate=[batch])
# Check validation results and raise an alert if validation fails
if not results["success"]:
raise ValueError("Data validation failed!")
# Define your ETL flow
with Flow("ETL_with_GE_Validation") as flow:
validation = validate_data()
# Execute the flow
flow.run()
在该示例中,我们定义了一个包含 Great Expectations 验证任务的 Prefect 流。
validate_data() 任务会加载 Great Expectations 上下文、获取数据批次并应用期望套件。
若数据未满足验证标准,该任务将抛出告警,停止工作流,防止下游错误。
持续数据验证
您可以使用多种工具调度验证作业,例如基于 Unix 的系统中的 cron 作业,或 Apache Airflow 等托管服务。本例将展示如何使用 Airflow 调度验证运行,它非常适合编排数据管道。
以下展示如何设置一个 Airflow DAG(有向无环图)以每日运行 Great Expectations 验证:
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import datetime
import great_expectations as ge
# Define the DAG and set the schedule to run daily
default_args = {
'owner': 'airflow',
'start_date': datetime(2024, 1, 1),
'retries': 1,
}
dag = DAG(
'great_expectations_validation',
default_args=default_args,
schedule_interval='@daily', # Runs once a day
)
# Define the function to run the validation
def run_validation():
context = ge.data_context.DataContext()
batch = context.get_batch(batch_kwargs, suite_name="your_expectation_suite")
results = context.run_validation_operator("action_list_operator", assets_to_validate=[batch])
return results
# Set up the task in Airflow
validation_task = PythonOperator(
task_id='run_great_expectations_validation',
python_callable=run_validation,
dag=dag,
)
# Set the task in the DAG
validation_task
在该示例中,我们定义了一个 DAG,按天调度运行一次(@daily)。
run_validation() 函数通过加载 Great Expectations 上下文并针对数据运行已定义的期望套件来执行验证。
使用 Great Expectations 进行数据验证的最佳实践
为实现可扩展与高效,遵循最佳实践始终是明智之举,数据验证亦然。
从小处着手,循序迭代
先从基础的数据质量检查开始,并逐步扩展。起初聚焦于基本期望更好,可避免过度复杂化流程,从而更顺利地集成并便于排障。随着您对数据集的理解加深,可添加更复杂的验证。
跨团队协作
数据质量不只是技术问题。与业务团队协作定义期望,确保实施的验证与底层业务逻辑和目标保持一致。此类跨职能协作能确保数据服务于既定目的,并满足各方需求。
尽可能自动化
尽可能将数据验证自动化并集成到数据管道中。自动化的验证检查可在无需人工干预的情况下持续监控数据质量,显著提升效率。
结语
做得很好!您已经学会了如何在 Great Expectations 中配置与验证数据。这些技巧将帮助您在工作流中保持高数据质量与透明度。
若想继续提升技能,请查看以下资源:
- ETL and ELT in Python:学习如何高效地转换与移动数据。
- Introduction to Data Quality:探索数据质量管理的基础知识。
- Cleaning Data in Python:掌握数据清洗技巧,确保准确性与一致性。
- Data Quality Dimensions Cheat Sheet:数据质量维度的便捷参考指南。
FAQs
Great Expectations 与其他数据验证工具相比如何?
Great Expectations 是开源、灵活的,并且能很好地与现代数据管道集成。它以丰富的期望库与强大的文档而脱颖而出。
使用 Great Expectations 需要懂 Python 吗?
具备基础的 Python 知识会有所帮助,但 Great Expectations 提供了用户友好的 CLI 和完善的文档,使非编程人员也能上手。
Great Expectations 支持哪些类型的数据源?
Great Expectations 支持广泛的数据源,包括:
- 关系型数据库,如 PostgreSQL、MySQL 与 SQL Server。
- 云存储方案,如 AWS S3、Google Cloud Storage 与 Azure Blob Storage。
- 文件格式,如 CSV、Parquet 与 Excel。
- 大数据框架,如 Apache Spark 与 Databricks。您可以通过为数据源配置相应参数,轻松将 Great Expectations 连接到这些来源。
我可以将 Great Expectations 用于流式数据吗?
Great Expectations 主要用于批处理数据验证。尽管其本身不原生支持流式数据管道,您可以通过定期验证数据快照或微批次,将其集成到 Apache Kafka 或 Spark Structured Streaming 等框架中。
能否对期望与验证结果进行版本控制?
可以。您可以将期望与配置以 YAML 或 JSON 文件形式存储在 Git 仓库中以进行版本控制。对于验证结果,您可以设置数据库或基于文件的存储来跟踪随时间的变化,并将其集成到 CI/CD 流水线中以实现持续监控。
Great Expectations 如何应对数据集的架构演进?
Great Expectations 通过灵活的期望框架来处理模式演进(schema evolution)。如果架构发生变化,您可以:
- 使用
expect_table_columns_to_match_set或类似期望以动态验证列名。 - 修改或创建新的期望套件以适配新架构。
- 借助架构推断工具,自动为新增列更新期望。