数据治理、质量与血缘:从 dbt 测试到 OpenLineage
0. 元信息
- 主题路径:
docs/topics/data-engineering-basics/subtopics/data-quality-and-lineage/README.md - 父主题:
data-engineering-basics - 适合对象:会写 SQL/Python、跑过数据流水线、希望从”数据能用”过渡到”数据可信、可追溯”的工程师
- 建议周期:2~2.5 周,每周 10~14 小时
- 前置知识:SQL、Python、Airflow;建议先完成父主题第 4 阶段
- 最终目标:能为给定数仓设计一套 dbt + Great Expectations + OpenLineage 的数据治理方案,并用 SQL/UI 查询血缘、配置质量门禁、定义数据契约
1. 学习路线
数据契约 → dbt 转换与测试 → Great Expectations 期望 → Soda 分布异常 → OpenLineage 血缘 → Marquez / DataHub 目录 → 可观测
2. 阶段周数分配
| 阶段 | 2 周方案 | 2.5 周方案 | 备注 |
|---|---|---|---|
| 1. 数据契约 | 1 天 | 1.5 天 | schema + owner + SLA + version |
| 2. dbt 转换 | 1.5 天 | 2 天 | staging / intermediate / marts |
| 3. dbt 测试 | 1.5 天 | 2 天 | 5 类测试 + 失败告警 |
| 4. Great Expectations | 1.5 天 | 2 天 | Expectation + Checkpoint |
| 5. Soda | 1 天 | 1.5 天 | SodaCL + 扫描 + 告警 |
| 6. OpenLineage | 1.5 天 | 2 天 | Run / Job / Dataset / Facet |
| 7. 数据目录 | 1 天 | 1.5 天 | Marquez / DataHub |
| 8. 治理落地 | 0.5 天 | 1 天 | SLA + On-call + 复盘 |
每天 1.5~2 小时。2 周方案专注前 5 阶段;2.5 周方案多 2 天做血缘与治理落地。
3. 核心知识 / 产出 / 标准表
| 阶段 | 核心知识 | 实践产出 | 可观察学会标准 |
|---|---|---|---|
| 1. 数据契约 | Schema、Owner、SLA、版本化、Schema Registry | 一份数据契约 YAML/Protobuf | 能讲清契约四要素 |
| 2. dbt 转换 | sources / staging / intermediate / marts、incremental、materialization | 一份 dbt 项目(5 模型) | 能跑通 dbt build |
| 3. dbt 测试 | unique / not_null / accepted_values / relationships / freshness | 5 类测试 + 失败告警 | 能解释 5 类测试与失败处置 |
| 4. Great Expectations | Expectation、Checkpoint、Data Docs | 10 条 Expectations + Data Docs 站点 | 能写出 5 种分布异常检测 |
| 5. Soda | SodaCL、Soda Core、扫描 + 失败告警 | 一份 Soda 检查 YAML | 能区分语法/语义/分布异常 |
| 6. OpenLineage | Run / Job / Dataset / Facet、Marquez | 一份 OpenLineage 事件流 + Marquez UI | 能用 SQL 查血缘 |
| 7. 数据目录 | DataHub / Unity Catalog、标签、Glossary | 一份带标签的目录 | 能查表/列/指标 |
| 8. 治理落地 | SLA、On-call、事故复盘 | 一份事故复盘 + 改进行动 | 能把质量问题接到 on-call |
4. 第一周(每天 1.5~2 小时)
Day 1 约定:本计划使用 Docker Compose 起 PostgreSQL + dbt + Great Expectations + Marquez。dbt 跑
dbt build/dbt test;GE 跑great_expectations checkpoint run;血缘事件用openlineage-client发到 Marquez HTTP endpoint。所有契约存为 YAML / Protobuf,版本化在 Git。
| 日 | 任务 | 当天交付 | 自检 |
|---|---|---|---|
| Day 1 | 装 Docker Compose + PostgreSQL + dbt-postgres + Great Expectations;用 dbt init 建一个 dbt 项目;写 sources.yml 指向 PostgreSQL raw.orders 表 | dbt 项目骨架 + sources.yml | dbt debug 通过;dbt run --select source:raw.orders 成功;SHOW SOURCES 含 raw.orders |
| Day 2 | 数据契约:写一份 contracts/orders.yaml(schema + owner + SLA + version 4 要素);用 Protobuf 翻译成 orders.proto;两份文件同时进 Git | 契约 YAML + Protobuf | YAML 4 要素齐;protoc --decode 输出与 YAML 一致;Git 提交记录显示版本号递增 |
| Day 3 | dbt 转换:写 3 层 dbt models(stg_orders / int_orders_cleaned / fct_orders_daily);dbt_project.yml 配 staging 视图、intermediate 增量、marts 物化表 | 3 层 dbt models + dbt_project.yml | dbt run 全部 success;dbt show --select fct_orders_daily 输出行数与源表一致;3 层命名规范符合 staging/intermediate/marts |
| Day 4 | dbt 测试:在 schema.yml 加 5 类测试(unique / not_null / accepted_values / relationships / freshness);故意制造 unique 冲突看测试失败;配 on-run-end 失败告警 | 5 类测试 + 失败日志 | dbt test 输出 5 passed;故意冲突后 dbt test 失败并打印 fail 详情;dbt build 失败时 exit code 非 0 |
| Day 5 | Great Expectations:用 great_expectations init 建 GE 项目;写 5 条 Expectations(ExpectColumnValuesToNotBeNull / ExpectColumnValuesToBeUnique / ExpectColumnValuesToBeBetween / ExpectColumnMeanToBeBetween / ExpectColumnStdevToBeBetween);配 Checkpoint | 5 条 Expectations + Checkpoint | great_expectations checkpoint run orders_checkpoint 输出 5 passed;Data Docs 站点可访问;ExpectColumnMeanToBeBetween 检测分布异常 |
| Day 6 | OpenLineage + Marquez:起 Marquez(docker compose up marquez);用 openlineage-client Python SDK 手动发一份 Run Start / Complete 事件;在 Marquez UI 查 Job → Dataset 血缘 | OpenLineage 事件脚本 + Marquez 截图 | Marquez UI 显示 Job 与 Dataset 节点;Run 事件含 run.facets.errorMessage 或 nominalTime;用 marquez-cli lineage get <dataset> 查 SQL 血缘 |
| Day 7 | 步骤 A:跑通 dbt + GE + OpenLineage 最小治理链路(dbt build → GE checkpoint → 发 OpenLineage 事件到 Marquez);步骤 B:补齐 4 类边界(契约漂移、测试失败阻塞、血缘事件丢失、SLA miss 不告警) | 治理链路 + 故障演练报告 | pytest -k test_data_governance 4 个用例全过;每类故障复现 + 防护措施写到 notes/week1-day7.md |
Day 7 执行次序
步骤 A —— 最小可用治理链路(60~90 分钟)
- dbt build 跑通(run + test);
- GE checkpoint 跑通(5 passed);
- 写 Python 脚本发 OpenLineage 事件到 Marquez;
- Marquez UI 看到血缘;
- 故意改源 schema 制造契约漂移,看告警。
步骤 B —— 4 类边界用例(30~45 分钟)
| # | 用例 | 期望行为 | 验证命令 |
|---|---|---|---|
| B1 | 契约漂移(源 schema 加列) | dbt 测试失败 + 告警 | pytest -k test_contract_drift |
| B2 | dbt 测试失败 | 阻塞下游 + Slack 告警 | pytest -k test_dbt_test_fail |
| B3 | OpenLineage 事件丢失 | 补发 + DLQ 告警 | pytest -k test_ol_event_lost |
| B4 | SLA miss 不告警 | 配 SLA checker + 强制告警 | pytest -k test_sla_alert |
Day 7 当天必完成步骤 A;步骤 B 至少完成 B1、B2。
5. 阶段通用验收
- 不看答案独立重写 dbt 3 层 + 5 类测试 + GE Checkpoint + OpenLineage 事件流;
- 用自己的话解释”为什么需要数据契约""为什么测试要阻塞下游""为什么血缘要列级而非仅表级”;
- 画一张图:契约 + 转换 + 测试 + 血缘全链路图(三件套之一);
- 测试契约漂移、测试失败、分布异常、血缘事件丢失、SLA miss 5 类边界;
- 准备至少 3 组自定义数据集并贴出实际测试结果与血缘截图;
- 记录 dbt build 时长、测试通过率、GE Checkpoint 失败率、OpenLineage 事件成功率 4 个核心指标;
- 能修改已有契约(加列 / 改 SLA)并验证血缘自动更新。
交付存放:第 3 项的图、第 5 项的输出、第 6 项的指标,统一存到
week1/notes/或week1/<dataset>/README.md。
6. 最终验收
-
独立设计并交付一套数据治理方案(dbt + GE/Soda + OpenLineage + Marquez),覆盖契约 / 测试 / 血缘 / SLA 4 大件;
-
至少完成 18 个实战项(分布建议):
子阶段 题目数量 难度 平台建议 数据契约 2 Easy / Medium Confluent SR / Protobuf dbt 转换与测试 4 Medium dbt 官方 Tutorial Great Expectations 4 Medium GE 官方 Examples Soda 2 Medium Soda 官方 Examples OpenLineage + 目录 4 Medium / Hard OpenLineage Spec + Marquez 治理落地 2 Hard Monte Carlo / Datafold 博客 约束:至少 9 项达到 Medium,至少 3 项达到 Hard;每项必须留可运行 dbt project + 测试报告 + 血缘截图。
-
完成 1 个综合项目:端到端治理(dbt + GE + OpenLineage + Marquez + Slack 告警 + 1 次故障复盘);
-
能用 15 分钟讲清数据契约四要素、5 类 dbt 测试、GE vs Soda 选型、OpenLineage 事件结构、Marquez 查血缘。
7. 综合项目
首选:端到端数据治理(必做:数据契约 + dbt + GE + OpenLineage + Marquez + Slack 告警)。
备选:分布异常监测(Soda + 历史基线 + 自动告警)。
备选:数据目录 + 治理门户(DataHub + dbt 集成 + 标签 + Glossary + 影响分析)。
端到端治理必做要求:
- 输入:订单 / 用户 / 商品 3 张源表(PostgreSQL)+ 至少 1 份 Protobuf 契约;
- 输出:必输出(1)dbt 3 层 models(staging / intermediate / marts)+ 5 类测试;(2)GE Checkpoint + Data Docs 站点;(3)OpenLineage 事件流到 Marquez;(4)Marquez UI 截图(Job / Dataset 血缘);(5)Slack 告警(dbt 测试失败 + GE Checkpoint 失败 + SLA miss);(6)1 次故障复盘(模拟契约漂移);
- 算法 / 工程:用
dbt build触发 OpenLineage 自动事件;用dbt source freshness配 SLA;用ge_checkpoint失败阻塞下游; - 进阶可选:用 Soda 做分布异常检测;接 Monte Carlo / Datafold 做可观测;用 Avatica / Trino 做数据查询入口。
任何综合项目都必须包含:
- 需求说明与数据契约(4 要素齐:schema + owner + SLA + version);
- 全链路架构图与命名规范;
- 核心代码(dbt models + GE Checkpoint + OpenLineage 事件 + Slack 告警 callback);
- 边界测试(契约漂移、测试失败、分布异常、血缘事件丢失、SLA miss);
- 可观测(GE Data Docs + Marquez UI + Slack 告警日志 + Grafana metrics);
- README(设计取舍、测试选型理由、下一步);
- 复盘记录(模拟 1 次 P0 故障,写
retrospective.md); - notes/ 规范:
| 文件 | 内容 |
|---|---|
notes/design.md | 全链路架构图 + 契约四要素表 + 命名规范 |
notes/test.md | 每组测试的输入 / 期望 / 实际 / 通过情况 |
notes/retrospective.md | 用时、难点、收获、改进点 |
notes/runbook.md | 常见失败 + 处置 SOP(契约漂移 / 测试失败 / 血缘缺失 / SLA miss) |
notes/marquez-screenshots/ | Marquez UI 截图(Job / Dataset / Column Lineage) |
notes/dbt-test-reports/ | dbt test 输出 + 失败详情 |
notes/contract-yaml/ | 数据契约(YAML + Protobuf 双份) |
notes/sample-data/ | 至少 3 组测试数据集 + 测试结果对比表 |
本主题贡献
数据治理的核心矛盾是”数据团队生产量大 vs 业务方不敢信”。本子主题专门讲清 Great Expectations + OpenLineage + Marquez 如何把这条信任墙拆掉——以 Great Expectations 为”期望即代码”的事实标准,OpenLineage 为血缘事件开放规范,Marquez 为血缘目录事实实现,SLA 为治理硬指标;不重复父主题的 dbt 基础与 Iceberg 存储。
3 职责
- 用 Great Expectations Checkpoint 把 10 条 Expectations(
ExpectColumnValuesToNotBeNull/ExpectColumnValuesToBeUnique/ExpectColumnValuesToBeBetween/ExpectColumnMeanToBeBetween/ExpectColumnStdevToBeBetween)做成可阻塞的质量门禁,失败阻塞下游 dbt run / Airflow Task。 - 用 OpenLineage 事件(Run Start / Complete / Fail,含
run.facets.errorMessage/nominalTime/dataset.facets.schema)把每个 Task 的输入输出数据集上报到 Marquez,血缘由”人维护”变成”自动产生”。 - 用 SLA 三件套(freshness / completeness / validity)为关键数据集定硬指标——
dbt source freshness+ GEExpectColumnValuesToNotBeNull+ MarqueznominalTime监控,SLA miss 接 Slack / PagerDuty 告警。
4 交付物
- 一份 Great Expectations 项目(10 条 Expectations + Checkpoint + Data Docs 站点),含 5 种分布异常检测(均值 / 标准差 / 分位数 / 唯一值比例 / NULL 比例),Checkpoint 失败 exit code 非 0。
- 一份 OpenLineage 事件脚本(Python
openlineage-clientSDK +dbt-ol集成 + Airflow OpenLineage provider),每个 Task 自动发 Run Start / Complete,含 Job / Dataset / Run Facet。 - 一份 Marquez 部署(
docker compose up marquez)+ 血缘查询示例(marquez-cli lineage get <dataset>),含 Job → Dataset 血缘截图 + 列级血缘验证。 - 一份 SLA 监控配置(
dbt source freshness+ GE Checkpoint + MarqueznominalTime监控),含 Slack / PagerDuty 告警 callback,SLA 文档写明 4 要素:freshness / completeness / validity / owner。
3 指标
- Great Expectations Checkpoint 通过率 ≥ 99%(失败 Checkpoint 阻塞下游,强制修复后重跑)。
- OpenLineage 事件成功率 ≥ 99.5%(Task 完成时事件必达 Marquez,缺失即告警)。
- SLA miss 告警响应 < 5 min(freshness 超时 → Slack 通知 → on-call 介入)。
8. 推荐开源资料
| 阶段 | 角色 | 资料 | 链接 | 用法 |
|---|---|---|---|---|
| 全部 | 主线书 | Reis & Housley《Fundamentals of Data Engineering》Ch.8~10 | https://www.oreilly.com/library/view/fundamentals-of-data/9781098108298/ | 治理与可观测必读 |
| 1 | 契约 | Confluent Schema Registry | https://docs.confluent.io/platform/current/schema-registry/index.html | 契约存储与兼容性 |
| 1 | 契约 | Protobuf 官方文档 | https://protobuf.dev/ | 跨语言 Schema |
| 2~3 | 转换 | dbt 官方文档 | https://docs.getdbt.com/ | 转换 + 测试 + 文档 |
| 4 | 质量 | Great Expectations 官方文档 | https://docs.greatexpectations.io/ | 期望即代码 |
| 5 | 质量 | Soda 官方文档 | https://docs.soda.io/ | SodaCL + Soda Core |
| 6 | 血缘 | OpenLineage 规范 | https://openlineage.io/ | 血缘事件标准 |
| 6 | 血缘 | Marquez 官方文档 | https://marquezproject.ai/ | 血缘 UI 实现 |
| 7 | 目录 | DataHub 官方文档 | https://datahubproject.io/ | 元数据目录 |
| 7 | 目录 | Unity Catalog 文档 | https://docs.unitycatalog.io/ | Databricks 目录 |
| 8 | 可观测 | Monte Carlo Blog | https://www.montecarlodata.com/blog/ | 数据可观测理念 |
| 8 | 可观测 | Datafold Blog | https://www.datafold.com/blog | 数据测试理念 |
许可证提示:dbt Core / GE / Soda / OpenLineage / Marquez / DataHub 都是 Apache-2.0;Unity Catalog 是商业版。复制 Apache 项目示例前请保留 LICENSE 与 NOTICE。默认做法是读规范后自己写测试与契约,而不是复制官方 Example。
默认使用顺序:先读 Reis《Fundamentals of Data Engineering》第 8~10 章建立治理心智 → 装 dbt + GE → 写数据契约(YAML + Protobuf)→ 写 dbt 3 层 models → 配 5 类 dbt 测试 → 加 GE Checkpoint + Data Docs → 起 Marquez + OpenLineage → 用 Slack 告警 → 跑端到端治理演练 → 写 notes/retrospective.md。
9. 学习资料汇聚(v0.3 自包含)
本节由本计划生成。链接指向原始材料或作者公开内容。规范会演进,记录时务必写明版本与日期。
9.1 背景与动机
数据团队的核心痛点不是”没数据”,而是”数据不可信”。脏数据进仓 → 错报表 → 错决策 → 业务损失。传统做法靠人工抽样检查,扩展性差。dbt 2016 年开源把”转换即代码 + 测试即代码”带入主流;Great Expectations 2018 年、Soda 2020 年先后开源,把”期望/检查即代码”做成事实标准。OpenLineage 2021 年由 Linux Foundation 发起,把血缘(lineage)从厂商特性做成开放标准,与 Marquez / DataHub / Unity Catalog 互操作。今天数据团队的”治理成熟度”由血缘完整度、契约覆盖率、测试通过率三项指标衡量。
9.2 概念地图
flowchart LR
Src[源系统] --> Contract[数据契约]
Contract --> Ingest[摄取]
Ingest --> Lake[Lakehouse]
Lake --> dbt[dbt 转换]
dbt --> Test[dbt 测试]
Lake --> GE[GE 期望]
dbt --> Soda[Soda 检查]
Test --> Gate[质量门禁]
GE --> Gate
Soda --> Gate
Gate --> Serve[服务 BI/API/ML]
dbt --> OL[OpenLineage 事件]
Ingest --> OL
Lake --> OL
OL --> MQ[Marquez]
OL --> DH[DataHub]
Serve --> Obs[可观测]
9.3 基础知识讲解
9.3.1 经典论文 / 规范
| 资料 | 贡献 | 读法 |
|---|---|---|
| OpenLineage Specification 1.x | 血缘事件标准 | 必读 Facet 部分 |
| Andrew Ng et al., Data Quality: The Foundation of Modern Data(2022) | 数据质量概念 | 选读 |
| Barrons et al., Data Contracts: A Unified Standard for Data(2023) | 数据契约 | 选读 |
9.3.2 经典书籍
| 书 | 侧重 | 用法 |
|---|---|---|
| Joe Reis & Matt Housley, Fundamentals of Data Engineering(O’Reilly 2022) | 数据工程生命周期 | 必读第 8~10 章 |
| Julien Kervizic, Observability for Data Engineering(Leanpub 2024) | 数据可观测 | 选读 |
| Svetlana Siccama, Data Quality Assessment(2023) | 数据质量评估 | 选读 |
9.3.3 优秀博客与文档
| 资料 | 特点 | 用法 |
|---|---|---|
| dbt 官方文档 | 转换 + 测试 + 文档 | 必读 |
| Great Expectations 官方文档 | 期望即代码 | 必读 Expectations + Checkpoint |
| Soda 官方文档 | SodaCL + Soda Core | 必读 SodaCL |
| OpenLineage 官方文档 | 血缘标准 | 必读 Spec |
| Monte Carlo Blog | 数据可观测理念 | 选读 |
| Datafold Blog | 数据测试 | 选读 |
9.3.4 核心人物
| 人物 | 影响 | 材料 |
|---|---|---|
| Drew Banin | dbt 起源 | dbt 博客 |
| Tristan Handy | dbt Labs | dbt 博客 |
| James Campbell | Soda 起源 | Soda 博客 |
| Abe Gong | Great Expectations | GE 博客 |
9.3.5 开发方法
| 方法 | 动作 | 何时用 |
|---|---|---|
| Contract-first | 先写契约,再写代码 | 任何新管道 |
| Test-as-code | 测试与模型同仓库 | 任何 dbt 项目 |
| Quality gate | 测试失败阻塞下游 | 上线前必加 |
| Lineage everywhere | 每个 Task 发 OpenLineage 事件 | 任何生产流水线 |
| SLI/SLO for data | 衡量 fresh / complete / valid | 任何关键数据集 |
9.4 经典问题与经典案例(≥5 道)
| # | 问题 | 重要性 | 最简答案 |
|---|---|---|---|
| 1 | 数据契约四要素 | 治理基础 | schema + owner + SLA + 版本 |
| 2 | dbt incremental 怎么写 | 性能 | 用 is_incremental() + unique_key |
| 3 | GE 与 Soda 怎么选 | 选型 | GE 重期望文档、Soda 重扫描 |
| 4 | OpenLineage 怎么接 | 血缘 | Airflow 用 OpenLineageProvider |
| 5 | 分布异常怎么检测 | 高级质量 | 用历史分布 + 偏差阈值 |
| 6 | 血缘表级 vs 列级 | 精细度 | 关键场景用列级(OpenLineage Column Lineage) |
| 7 | 数据测试 CI/CD | 工程化 | 用 dbt build + GitHub Actions |
| 8 | SLA miss 怎么告警 | 反馈链路 | 用 SLA checker + Slack |
| 9 | Schema Registry 怎么选 | 契约存储 | Confluent SR / Apicurio / 自建 |
| 10 | 数据可观测 vs 监控 | 概念 | 监控看指标、可观测看变化原因 |
9.5 学习难点
概念难点
| 难点 | 突破路径 |
|---|---|
| 契约 vs Schema | 写四要素对照 |
| 测试 vs 检查 | dbt 测试重静态、Soda 重动态 |
| 血缘 vs 影响分析 | 血缘是依赖,影响是变更爆炸半径 |
思维难点
| 难点 | 突破路径 |
|---|---|
| 阈值怎么设 | 用历史分布 + 业务 SLA |
| 血缘覆盖率 | 看”关键数据集是否有 owner + SLA” |
工程难点
| 难点 | 突破路径 |
|---|---|
| dbt 项目膨胀 | 用 staging / intermediate / marts 三层 |
| GE 大检查超时 | 用 Checkpoint 拆分 |
| OpenLineage 事件丢失 | 加 retry + DLQ |
9.6 技术标准与接口
Entity
| 名称 | 版本 | 组织 | 状态 | 许可证 |
|---|---|---|---|---|
| dbt Core / Cloud | 1.x / 最新 | dbt Labs | 活跃 | Apache-2.0 / 商业 |
| Great Expectations | 0.18+ | GE | 活跃 | Apache-2.0 |
| Soda Core | 3.x | Soda Data | 活跃 | Apache-2.0 |
| OpenLineage | 1.x | OpenLineage | 活跃 | Apache-2.0 |
| Marquez | 1.x | OpenLineage | 活跃 | Apache-2.0 |
| DataHub | 0.x | LinkedIn / DataHub | 活跃 | Apache-2.0 |
| Unity Catalog | — | Databricks | 商业 | 商业 |
| Apache Atlas | 2.x | Apache | GA | Apache-2.0 |
Scope
dbt 是转换 + 测试;GE / Soda 是质量检查;OpenLineage 是血缘标准;Marquez / DataHub / Atlas 是目录实现。它们互补,不替代。
Structure
- dbt:
sources → staging → intermediate → marts,测试写在schema.yml。 - GE:
ExpectationSuite → Checkpoint → Data Docs。 - Soda:
SodaCL 检查定义 → Soda Core 扫描 → 告警。 - OpenLineage:
run / job / dataset / facet,事件推送到 HTTP 或 Kafka。 - 数据契约:
schema + owner + SLA + version,可入 Schema Registry。
Ecosystem
- 转换:dbt、SQLMesh、Coalesce。
- 质量:GE、Soda、Monte Carlo、Datafold、Bigeye。
- 血缘:OpenLineage、Marquez、DataHub、Apache Atlas、Unity Catalog。
- 契约:Schema Registry (Confluent / Apicurio)、Protobuf、Avro。
Depth Tiers
| 层级 | 能力 | 标准 |
|---|---|---|
| L0 | 知道存在 | 知道 dbt/GE/Soda/OpenLineage 各自定位 |
| L1 | 看得懂示例 | 能读懂 dbt model + schema.yml |
| L2 | 能正确调用 | 能用 dbt build + GE Checkpoint |
| L3 | 能解释与排错 | 能定位血缘缺失、契约漂移、测试失败 |
| L4 | 能设计与扩展 | 能设计整套数据治理框架 |
本子主题目标:L3。
Source
- dbt 官方文档:引用快照 2026-07-30。
- Great Expectations 官方文档:引用快照 2026-07-30。
- OpenLineage 官方文档:引用快照 2026-07-30。
9.7 关键代码
9.7.1 dbt model + schema.yml(5 类测试)
# 9.7.1 dbt project/models/staging/schema.yml
version: 2
models:
- name: stg_orders
columns:
- name: order_id
tests:
- unique
- not_null
- name: user_id
tests:
- not_null
- relationships:
to: ref('stg_users')
field: user_id
- name: status
tests:
- accepted_values:
values: ['pending', 'paid', 'shipped', 'cancelled']
- name: order_date
tests:
- not_null
- name: amount
tests:
- not_null
config:
contract:
enforced: true
-- 9.7.1.2 dbt incremental model
{{ config(materialized='incremental', unique_key='order_id') }}
SELECT
order_id,
user_id,
amount,
order_date,
status
FROM {{ source('raw', 'orders') }}
{% if is_incremental() %}
WHERE order_date > (SELECT MAX(order_date) FROM {{ this }})
{% endif %}
9.7.2 Great Expectations Checkpoint
# 9.7.2 Great Expectations 配置 + Checkpoint
import great_expectations as gx
context = gx.get_context(mode="file", project_root_dir="./gx")
batch = context.get_batch(
batch_definition=context.data.add_pandas_filesystem(
name="orders", base_directory="./data"
),
batch_parameters={"path": "./data/orders.parquet"},
)
suite = context.suites.add(
gx.ExpectationSuite(name="orders_suite")
)
suite.add_expectation(gx.expectations.ExpectColumnValuesToNotBeNull(column="order_id"))
suite.add_expectation(gx.expectations.ExpectColumnValuesToBeUnique(column="order_id"))
suite.add_expectation(gx.expectations.ExpectColumnValuesToBeBetween(
column="amount", min_value=0, max_value=1_000_000
))
suite.add_expectation(gx.expectations.ExpectColumnMeanToBeBetween(
column="amount", min_value=10, max_value=10_000
))
checkpoint = context.checkpoints.add(
gx.Checkpoint(name="orders_checkpoint", suites=[suite], actions=[
gx.checkpoint.UpdateDataDocsAction(name="docs"),
])
)
checkpoint.run(batch=batch)
9.7.3 OpenLineage + Airflow
# 9.7.3 Airflow + OpenLineage Provider 配置
from airflow import DAG
from airflow.providers.openlineage.sensors.openlineage import OpenLineageSensor
from airflow.operators.bash import BashOperator
dag = DAG("orders_etl", openlineage_integration=True)
extract = BashOperator(
task_id="extract",
bash_command="echo extract",
dag=dag,
inlets=[{"type": "database", "name": "raw.orders"}],
outlets=[{"type": "table", "name": "dw.ods_orders"}],
)
10. 常见误区
- 把数据质量当监控看,不挂门禁;
- dbt 测试只写 unique / not_null;
- 契约只在文档里写,不入 Schema Registry;
- GE 期望只写语法不写分布;
- OpenLineage 事件只发 Task 起点不终点;
- 血缘只画表级不看列级;
- SLA 写了不告警;
- 数据目录没人维护;
- dbt 项目没有 staging/intermediate/marts 分层;
- 增量模型缺 unique_key 导致重复;
- 数据契约没 owner,事故找不到人;
- 质量事故不复盘。
11. 所有知识点分类
- 编程语言
- 数据结构与算法
- 计算机基础
- 工程技术
- Web 与后端
- 前端与客户端
- 数据与人工智能
- 项目与职业能力
- 安全与可靠性
本计划归属:数据与人工智能 主 + 工程技术 辅。