ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Data Engineering Zoomcamp 实战:用 schema.yml 构建 dbt 数据文档体系

Data Engineering Zoomcamp 实战:用 schema.yml 构建 dbt 数据文档体系 Data Engineering Zoomcamp 实战用 schema.yml 构建 dbt 数据文档体系【免费下载链接】data-engineering-zoomcampData Engineering Zoomcamp is a free 9-week course on building production-ready data pipelines. Join the course here 项目地址: https://gitcode.com/GitHub_Trending/da/data-engineering-zoomcamp本指南对应 Data Engineering Zoomcamp 第 4 周「Analytics Engineering」课程笔记 4.5.1主题为 dbt 的 Documentation 机制。在taxi_rides_nydbt 项目中当模型全部构建完成后文档化的核心问题有三个写什么、写在哪里、dbt 拿到这些 YAML 之后会做什么。读完本文你将掌握用schema.yml为 source、model、column、macro、seed 编写描述与元数据的完整规范理解|与多行文本的区别并能用dbt docs generatedbt docs serve生成可交互的文档站点从血缘图中定位模型依赖关系。文档放在哪里一切都是 YAML 文件在接触 dbt sources 时你已经见过 YAML 文件但 YAML 的职责远不止声明原始数据在哪——它是整个 dbt 项目最主要的文档载体。模型描述、列描述、测试声明、自定义元数据全部以声明式 YAML 的形式与模型代码并排存放。最常见的约定是每个目录下一个schema.yml。本课程的taxi_rides_ny项目正是遵循这一约定models/staging/schema.yml —— 描述stg_green_tripdata、stg_yellow_tripdata两个 staging 模型models/intermediate/schema.yml —— 描述int_trips_unioned、int_trips两个中间层模型models/marts/schema.yml —— 描述dim_zones、dim_vendors、fct_trips三个 mart 模型models/marts/reporting/schema.yml —— 描述报表层fct_monthly_zone_revenue也有一些团队偏好每个模型一个 YAML 文件当项目规模变大、单个 schema.yml 膨胀到难以维护时这种按模型拆分的做法同样合理。两种方式在 dbt 中的解析结果完全等价选择取决于团队习惯。从项目配置可以确认 dbt 会自动扫描这些目录dbt_project.yml 中声明了model-paths: [models]、seed-paths: [seeds]、macro-paths: [macros]、test-paths: [tests]dbt 会从这些路径递归发现 YAML 属性文件。一切皆可文档化统一的 YAML 模式无论文档化哪种对象结构都是同一套模式version: 2作为文件头然后切换不同的顶层键sources:、models:、seeds:、macros:为每个对象写上name和description再向下钻取到列级别。Sources给原始数据层写说明taxi_rides_ny项目中原始数据层的文档位于 models/staging/sources.yml。你可以为 source 本身、source 下每个表、以及表下每一列分别写描述sources: - name: raw description: Raw taxi trip data from NYC TLC database: | {%- if target.type bigquery -%} {{ env_var(GCP_PROJECT_ID, please-add-your-gcp-project-id-here) }} {%- else -%} taxi_rides_ny {%- endif -%} schema: | {%- if target.type bigquery -%} nytaxi {%- else -%} prod {%- endif -%} tables: - name: green_tripdata description: Raw green taxi trip records columns: - name: vendorid description: Taxi technology provider (1 Creative Mobile Technologies, 2 VeriFone Inc.) - Note: Raw data may contain nulls, filtered in staging - name: lpep_pickup_datetime description: Date and time when the meter was engaged ... config: freshness: warn_after: {count: 24, period: hour} error_after: {count: 48, period: hour}这份真实源码还展示了两个超出文档化本身的进阶用法database/schema字段可以内嵌 Jinjasources.yml中通过target.type判断当前连接的是 BigQuery 还是本地 DuckDB/Postgres从而动态切换库名与 schema 名。这意味着文档属性文件不只是静态文本而是编译期可编程的配置。freshness数据新鲜度声明warn_after: 24h/error_after: 48h配合loaded_at_field使用让 dbt 能够对 source 做新鲜度探测——这是 source 独有的、模型文档中没有的能力。Modelsschema.yml 中的核心部分在schema.yml中把顶层键从sources:换成models:思路完全一致——给每个模型写名称和描述然后向下钻取到列。课程笔记给出的经典示例version: 2 models: - name: dim_zones description: Zone lookup table containing LocationID, borough, zone name and service zone. One row per taxi zone in NYC. columns: - name: locationid description: Primary key for taxi zones tests: - unique - not_null - name: borough description: NYC borough name (Manhattan, Queens, Brooklyn, Bronx, Staten Island, EWR) - name: zone description: Taxi zone name/neighborhood - name: service_zone description: Service zone type (Yellow, Green, or Airports)仓库中 models/marts/schema.yml 是这一模式的完整落地dim_zones、dim_vendors、fct_trips三个模型均有 description且每个列都标注了业务含义例如fct_trips中- name: fct_trips description: Fact table with all taxi trips including trip and payment details config: contract: enforced: true columns: - name: trip_id description: Unique trip identifier data_type: string data_tests: - unique - not_null - name: pickup_zone description: Specific zone where trip started data_type: string ...Columns每一列都值得一段说明课程笔记明确列出了列的五个可配置属性name—— 必须与实际列名完全一致dbt 用它把文档属性绑定到具体的列description—— 这一列的业务含义data_type—— 期望的列类型注意默认是信息性的dbt 不会强制校验tests/data_tests—— 测试声明槽位下一节视频会详细展开meta—— 自定义键值标签详见下文一个值得注意的版本细节课程笔记写作时使用的是tests:关键字而当前仓库中的 schema.yml 全部写作data_tests:。这是 dbt 1.8 起的命名调整tests更名为data_tests以与unit_tests区分两种写法在不同 dbt 版本中兼容性不同。当前项目在 dbt_project.yml 中声明require-dbt-version: [1.7.0, 3.0.0]并开启了flags.require_generic_test_arguments_property: true因此采用新的data_tests写法。另外注意fct_trips模型在 schema.yml 中带了一个config: contract: enforced: true。这意味着该模型启用了dbt model contract当合约强制开启时data_type就不再只是信息性提示而会成为建表时的约束与实际数据库 schema 强校验——这是对课程笔记中data_type 仅供参考说法的重要补充。Macros 和 Seeds同一个 YAML 模式宏与种子数据也可以文档化模式完全一致同样的version: 2头只是顶层键换成macros:与seeds:。macros/macros_properties.yml 为两个跨数据库宏编写了文档宏文档额外支持arguments段macros: - name: get_trip_duration_minutes description: Calculates trip duration in minutes from pickup and dropoff timestamps. This macro is cross-database compatible, supporting both DuckDB and BigQuery. Returns a numeric value representing the duration in minutes. arguments: - name: pickup_datetime type: timestamp description: The pickup timestamp - name: dropoff_datetime type: timestamp description: The dropoff timestamp与之对应宏在真实模型中的调用见 models/marts/fct_trips.sql 第 37 行{{ get_trip_duration_minutes(trips.pickup_datetime, trips.dropoff_datetime) }} as trip_duration_minutes——文档中的参数定义与实际调用一一对应。seeds/seeds_properties.yml 则文档化了taxi_zone_lookup与payment_type_lookup两个种子其中payment_type_lookup还带着列级描述与unique、not_null测试seeds: - name: taxi_zone_lookup description: Taxi Zones roughly based on NYC Department of City Plannings Neighborhood Tabulation Areas (NTAs) and are meant to approximate neighborhoods... - name: payment_type_lookup description: Payment type reference data mapping payment type codes to their descriptions. Used as a dimension table for payment method analysis. columns: - name: payment_type description: Numeric code for payment type data_tests: - unique - not_null - name: description description: Human-readable description of payment method多行描述|与的差异当一段描述需要换行书写时使用 YAML 的管道符|或大于号。两者行为有明确区别folding把换行折叠为空格最终渲染成一段连续的文本适合较长的散文式说明|literal保留换行原文排版被原样保留课程笔记用fct_trips的多行描述演示了|的用法version: 2 models: - name: fct_trips description: | Fact table containing all taxi trips from both yellow and green taxis. This is the core analytical table for trip-level analysis. Each row represents a single trip with: - Trip identifiers and service type - Pickup and dropoff locations and timestamps - Trip details (distance, passenger count, etc.) - Payment information and amounts Data is filtered for 2019-2020 only and excludes records with unknown pickup or dropoff locations.在仓库中staging 层的 models/staging/schema.yml 大量使用了折叠风格来撰写模型级描述例如- name: stg_green_tripdata description: Staging model for green taxi trip data. This model standardizes column names and data types from the raw green_tripdata source, providing a clean foundation for downstream transformations.一个实用的写作建议模型级描述用写出流畅的段落需要保留结构化信息列表、空行、字段清单时改用|两者搭配可以让文档既易读又信息完整。Meta 标签自定义元数据meta字段允许你给任意列或模型挂上任意键值对。它没有预定义集合——你和你的团队决定什么值得记录。课程笔记给出的常见用法PII—— 标记包含个人身份信息的列如支付、联系方式相关字段供治理与合规审查owner—— 数据资产负责人出问题时知道该找谁importance—— 区分关键列与参考列关键认知meta不会影响 dbt 的任何运行行为它纯粹服务于治理governance、可发现性discoverability和团队协作导航。这也意味着它非常适合承载公司内部的数据字典规范、血缘审批规则等人读的信息而不会污染 SQL 编译结果。生成并浏览文档模型、描述、测试都写好后剩下的是两个按顺序执行的命令。dbt docs generate把一切编译成 JSON该命令会把三部分信息编译进 JSON 文件你写在 YAML 里的全部描述source / model / column / macro / seed模型代码Jinja 原始版本 编译后的 SQL从数据仓库采集的元数据如实际的列类型、表大小等在dbt Cloud中该步骤自动执行甚至有对应勾选项在dbt Core中需要手动运行。生成的产物写入target/目录——从 dbt_project.yml 的clean-targets: [target, dbt_packages]可以看出target是 dbt 的编译与文档产物目录dbt clean会清空它。dbt docs serve本地起一个文档站点该命令读取上一步生成的 JSON在本机启动一个本地网站默认地址localhost:8080。它只在 dbt Core 场景下需要——dbt Cloud 会替你托管文档。如果希望团队成员也能访问需要自行托管例如 S3、Netlify 等静态站点托管服务。文档站点能看到什么生成的文档站点提供四类核心信息模型代码—— 既有你手写的 Jinja 版本也有最终会打到数据库的编译后 SQL方便排查写的是什么与跑的是什么之间的差异列信息—— 类型、描述以及你添加的一切属性血缘图Lineage Graph—— 一个可视化的 DAGsource 以绿色呈现一路延伸到最终的 mart 模型。可以直观看到每个节点依赖谁、又被谁依赖从而判断改动某个模型是否会破坏下游项目结构—— 在文件夹视图与数据库视图之间切换浏览值得一提的是血缘图与仓库中的模型依赖关系完全对应例如 models/marts/fct_trips.sql 通过{{ ref(int_trips) }}与两次left join {{ ref(dim_zones) }}建立依赖而 models/marts/dim_zones.sql 通过{{ ref(taxi_zone_lookup) }}依赖种子——这些ref()关系会被 dbt 自动解析进血缘图。定位技术文档工具而非数据目录课程笔记给出了一个清醒的定位dbt 的文档站点更偏向技术文档工具而不是精美的企业级数据目录data catalog。它不会替代 Looker 或 Confluent 那类面向非技术业务人员的目录产品。但对真正在构建模型的工程师来说它足够实用——一眼就能看清项目里有哪些数据资产、它们如何连接、各自做什么。在taxi_rides_ny项目中这套体系的最终效果是从 models/staging/sources.yml 的原始 NYC TLC 数据经过 models/staging/schema.yml 的标准命名与类型规范、models/intermediate/schema.yml 的清洗去重与service_type归一化再到 models/marts/schema.yml 的星型模型每一层都有与之配套的文档与测试声明。文档与代码同源、同目录、同版本演进这才是 dbt documentation-as-code 的核心价值文档不再是滞后于代码的孤立产物而是与模型一起被编译、被校验、被版本化的一部分。小结五个关键要点文档载体是 YAMLschema.yml约定每目录一个或每模型一个两种皆可模式统一version: 2 顶层键sources:/models:/seeds:/macros: 逐级向下钻取到列多行文本折叠换行适合散文|保留换行适合结构化说明meta不参与运行只服务于治理与可发现性data_type默认仅供参考开启 model contract 后才会被强制校验两步出文档dbt docs generate编译 JSONdbt docs serve起本地站点默认localhost:8080血缘图、编译后 SQL、列信息一应俱全【免费下载链接】data-engineering-zoomcampData Engineering Zoomcamp is a free 9-week course on building production-ready data pipelines. Join the course here 项目地址: https://gitcode.com/GitHub_Trending/da/data-engineering-zoomcamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表