Chapter 05

文档(Documentation)

让数据资产自带文档——模型描述、列定义、自动血缘图,一键生成静态文档站

5.1 为什么数据文档至关重要

在传统数据团队中,文档通常是事后补充的,或干脆不存在。当新同事加入时,他们不知道 dim_customers 表里的 ltv 字段是怎么计算的;当 BI 报表出现异常时,没人知道数据从哪来、经过了什么转换。

dbt 将文档视为一等公民:描述(description)与代码共存,文档自动从代码生成,而非单独维护。这确保文档永远与实际代码保持同步。

5.2 在 schema.yml 中添加描述

在 schema.yml 中,可以为模型和每个列添加 description 字段:

YAML# models/marts/schema.yml
version: 2

models:
  - name: customer_orders
    description: |
      客户订单汇总宽表,每行代表一个客户的历史订单聚合数据。
      用于 BI 报表中的"客户价值分析"仪表盘。
      更新频率:每日 UTC 03:00。

    columns:
      - name: customer_id
        description: "客户唯一标识符,来源于 ecommerce.customers.customer_id"

      - name: total_orders
        description: "该客户的历史总订单数(包含已取消的订单)"

      - name: lifetime_value
        description: >
          客户终身价值(LTV),定义为所有状态为 COMPLETED 的订单金额之和,
          单位:美元,保留两位小数。计算不包含退款订单。

      - name: first_order_date
        description: "客户首次下单日期,用于计算客户生命周期"

      - name: most_recent_order_date
        description: "客户最近一次下单日期,用于判断客户活跃状态"

5.3 docs block — 长描述的复用

对于多个模型共用的字段描述(如标准的 customer_id 定义),可以用 docs block 统一维护,避免重复:

MARKDOWN">-- models/docs.md
{% docs customer_id %}
客户唯一标识符(UUID v4 格式)。
- 来源:ecommerce PostgreSQL 系统,表 `public.customers.id`
- 由 Fivetran 同步至数仓 raw 层
- 不允许为 NULL,全局唯一
- 示例值:`550e8400-e29b-41d4-a716-446655440000`
{% enddocs %}

{% docs order_status %}
订单当前状态,枚举值:
- `PENDING`:已下单,待付款
- `COMPLETED`:已完成,货款已结清
- `CANCELLED`:用户取消
- `REFUNDED`:已退款

状态变更逻辑:PENDING → COMPLETED 或 PENDING → CANCELLED → REFUNDED
{% enddocs %}
YAML# 在 schema.yml 中引用 docs block
models:
  - name: stg_orders
    columns:
      - name: customer_id
        description: "{{ doc('customer_id') }}"   # 引用 docs block
      - name: status
        description: "{{ doc('order_status') }}"

5.4 生成文档站:dbt docs generate

BASH# 生成文档(会在 target/ 目录创建静态文件)
dbt docs generate

# 本地预览(启动一个本地 HTTP 服务器,默认端口 8080)
dbt docs serve

# 指定端口
dbt docs serve --port 8081

访问 http://localhost:8080 即可查看交互式文档站,包含:

5.5 血缘图(Lineage Graph)

dbt 文档站最强大的功能之一是自动生成的血缘图。它展示数据如何从原始 source 经过多层转换,最终流向 mart 层和 BI 工具:

source: ecommerce.orders
stg_orders
int_orders_enriched
fct_orders
source: ecommerce.customers
stg_customers
dim_customers
🔍

血缘图是 dbt 文档的核心价值 当 BI 仪表盘数据出现异常时,分析师可以在血缘图中追溯到具体的原始数据源,快速定位问题。这在传统 ETL 工具中通常需要数小时的排查工作。

5.6 Exposures — 声明下游消费者

Exposures 用于声明 dbt 模型的下游消费者(BI 报表、API、ML 模型等),让血缘图延伸到数据仓库之外:

YAML# models/exposures.yml
version: 2

exposures:
  - name: customer_dashboard
    type: dashboard
    maturity: high
    url: https://your-bi-tool.com/dashboards/customer-overview
    description: "客户价值分析仪表盘,每日更新"
    owner:
      name: 数据团队
      email: data-team@company.com
    depends_on:
      - ref('customer_orders')
      - ref('dim_customers')

  - name: ltv_prediction_model
    type: ml
    maturity: medium
    description: "客户 LTV 预测模型,每周训练"
    owner:
      name: ML 团队
      email: ml-team@company.com
    depends_on:
      - ref('customer_orders')

5.7 与 GitHub Pages 集成发布

将 dbt 生成的静态文档自动部署到 GitHub Pages:

YAML# .github/workflows/docs.yml
name: Deploy dbt Docs

on:
  push:
    branches: [main]

jobs:
  deploy-docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install dbt
        run: pip install dbt-core dbt-duckdb

      - name: Generate docs
        run: |
          dbt deps
          dbt docs generate
        env:
          DBT_PROFILES_DIR: .

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./target
          destination_dir: docs
📌

本章小结
dbt 文档与代码共存,通过 schema.yml 的 description 字段为模型和列添加描述;docs block(在 .md 文件中定义)支持长描述的跨文件复用。

dbt docs generate 将 YAML 描述、编译 SQL、血缘关系生成为静态 HTML 站;dbt docs serve 本地预览。Exposures 声明 BI 报表等下游消费者,让血缘图完整延伸。通过 GitHub Actions 可以自动部署到 GitHub Pages。