第3部分:测试、文档与部署 🚀
抱歉,我需要您提供要翻译的具体文本内容才能进行翻译。请把文章的正文(除代码块和链接外)粘贴在这里,我会按照要求将其翻译成简体中文并保留原有的格式。
数据工程 Zoomcamp
#dbt #AnalyticsEngineering #DataModeling
Macros – 可复用的 SQL 函数 🔧
没有宏(重复代码)
-- ❌ Repeated everywhere
CASE
WHEN payment_type = 1 THEN 'Credit card'
WHEN payment_type = 2 THEN 'Cash'
WHEN payment_type = 3 THEN 'No charge'
WHEN payment_type = 4 THEN 'Dispute'
WHEN payment_type = 5 THEN 'Unknown'
ELSE 'Unknown'
END AS payment_type_description
使用宏(一次编写)
-- macros/get_payment_type_description.sql
{% macro get_payment_type_description(payment_type) %}
CASE {{ payment_type }}
WHEN 1 THEN 'Credit card'
WHEN 2 THEN 'Cash'
WHEN 3 THEN 'No charge'
WHEN 4 THEN 'Dispute'
WHEN 5 THEN 'Unknown'
ELSE 'Unknown'
END
{% endmacro %}
在任意模型中使用
-- models/staging/stg_green_tripdata.sql
SELECT
payment_type,
{{ get_payment_type_description('payment_type') }} AS payment_type_description
FROM {{ source('staging', 'green_tripdata') }}
| 语法 | 用途 | 示例 |
|---|---|---|
{{ }} | 输出表达式 | {{ ref('my_model') }} |
{% %} | 逻辑/控制流 | {% if is_incremental() %} |
{# #} | 注释 | {# This is a comment #} |
软件包 – 重用他人构建的宏和模型
| Package | What it Does |
|---|---|
| dbt_utils | 常用的 SQL 辅助工具(代理键、透视等) |
| dbt_codegen | 自动生成 YAML 和 SQL |
| dbt_expectations | Great Expectations 风格的测试 |
| dbt_audit_helper | 在重构时比较模型输出 |
创建 packages.yml
packages:
- package: dbt-labs/dbt_utils
version: 1.1.1
安装软件包
dbt deps
使用软件包中的宏
-- 使用 dbt_utils 生成代理键
SELECT
{{ dbt_utils.generate_surrogate_key(['vendorid', 'pickup_datetime']) }} AS trip_id,
*
FROM {{ source('staging', 'green_tripdata') }}
Tests – Ensure data meets expectations
1️⃣ Generic Tests (most common)
Add them in a schema YAML file:
# models/staging/schema.yml
version: 2
models:
- name: stg_green_tripdata
columns:
- name: trip_id
tests:
- unique # No duplicate values
- not_null # No null values
- name: payment_type
tests:
- accepted_values:
values: [1, 2, 3, 4, 5, 6] # Allowed values only
- name: pickup_location_id
tests:
- relationships: # Referential integrity
to: ref('dim_zones')
field: location_id
| Test | Description |
|---|---|
unique | 列中没有重复值 |
not_null | 列中没有 NULL 值 |
accepted_values | 值必须在指定列表中 |
relationships | 值必须存在于另一张表中 |
2️⃣ Singular (custom) Tests
Place a .sql file in the tests/ folder:
-- tests/assert_positive_fare_amount.sql
-- Test FAILS if any rows are returned
SELECT
trip_id,
fare_amount
FROM {{ ref('fct_trips') }}
WHERE fare_amount < 0
Fact table containing all taxi trips (yellow and green).
One row per trip with fare details and zone information.
Generate & serve docs
dbt docs generate # Build the site
dbt docs serve # Open in a browser
The site includes:
- Model descriptions
- Column definitions
- Dependency graph (visual DAG)
- Source information
常用 dbt 命令
| 命令 | 功能 |
|---|---|
dbt run | 构建所有模型(创建视图/表) |
dbt test | 运行所有测试 |
dbt build | 同时运行模型和测试(推荐) |
dbt compile | 生成 SQL 而不执行 |
dbt debug | 检查连接和项目配置 |
dbt seed | 加载 seed CSV 文件 |
dbt deps | 安装包 |
dbt docs generate | 生成文档 |
dbt docs serve | 本地提供文档服务 |
dbt retry | 重试失败的模型 |
选择特定模型
# Single model
dbt run --select stg_green_tripdata
# Model + all upstream dependencies
dbt run --select +fct_trips
# Model + all downstream models
dbt run --select stg_green_tripdata+
# Both directions
dbt run --select +fct_trips+
# All models in a folder
dbt run --select staging.*
# Multiple models
dbt run --select stg_green_tripdata stg_yellow_tripdata
# Development (default target)
dbt run
# Production target
dbt run --target prod
物化(Materializations)— dbt 如何持久化模型
| 类型 | 创建内容 | 典型使用场景 |
|---|---|---|
view | SQL 视图(查询已存储,访问时执行) | 暂存模型,逻辑经常变化 |
table | 物理表(数据已存储) | 最终数据集市,大数据集,性能关键查询 |
incremental | 仅追加新数据 | 超大表,事件式数据 |
ephemeral | 不创建(在下游作为 CTE) | 辅助模型,中间步骤 |
在模型文件中设置物化
{{ config(materialized='table') }}
SELECT *
FROM {{ ref('stg_trips') }}
或在 dbt_project.yml 中全局设置
models:
my_project:
staging:
materialized: view
marts:
materialized: table
快速决策助手
┌─────────────────────────────────────────────────────────────┐
│ Should I use a view or a table? │
└─────────────────────────────────────────────────────────────┘
当底层逻辑经常变化,或数据集足够小,以至于在每次查询时重新计算成本低廉时,使用 view。
当您需要持久化数据以提升性能、供下游使用,或数据集庞大且重新计算成本高时,使用 table。
Decision Flow
▼
┌──────────────────────────┐
│ Is the query expensive? │
└──────────────────────────┘
│ │
Yes No
│ │
▼ ▼
┌─────────┐ ┌─────────┐
│ TABLE │ │ VIEW │
└─────────┘ └─────────┘
使用 VIEW 的情况
- 暂存模型(简单转换)
- 逻辑经常变更
- 存储成本是考虑因素
使用 TABLE 的情况
- 最终数据集经常被查询
- 复杂的连接/聚合
- 查询性能很重要
项目概览 – NYC 出租车数据
┌──────────────────────────────────────────────────────────────┐
│ RAW DATA │
│ green_tripdata (GCS/BigQuery) │ yellow_tripdata (GCS/BigQuery)│
└───────────────────┬─────────────────────┬────────────────────┘
│ │
▼ ▼
┌──────────────────────────────────────────────────────────────┐
│ STAGING LAYER │
│ stg_green_tripdata │ stg_yellow_tripdata │
│ (cleaned, renamed) │ (cleaned, renamed) │
└───────────────────┬─────────────────────┬────────────────────┘
│ │
└──────────┬──────────┘
│
▼
┌──────────────────────────────────────────────────────────────┐
│ INTERMEDIATE LAYER │
│ int_trips_unioned │
│ (green + yellow combined) │
└───────────────────────────────┬──────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────┐
│ MARTS LAYER │
│ ┌─────────────┐ ┌───────────────┐ ┌─────────────────────┐ │
│ │ dim_zones │ │ fct_trips │ │ fct_monthly_zone_rev │ │
│ │ (dimension)│ │ (fact) │ │ (report) │ │
│ └─────────────┘ └───────────────┘ └─────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
模型目录
| Model | Type | Description |
|---|---|---|
stg_green_tripdata | Staging | 已清洗的绿色出租车数据 |
stg_yellow_tripdata | Staging | 已清洗的黄色出租车数据 |
int_trips_unioned | Intermediate | 合并的黄色 + 绿色行程 |
dim_zones | Dimension | 区域查找表 |
fct_trips | Fact | 每次行程对应一行 |
fct_monthly_zone_revenue | Report | 按区划分的月度收入 |
本地开发(DuckDB)
优点: 免费,无需云账户
缺点: 受限于机器资源
# 1. Install dbt with the DuckDB adapter
pip install dbt-duckdb
# 2. Clone the project
git clone https://github.com/DataTalksClub/data-engineering-zoomcamp
cd data-engineering-zoomcamp/04-analytics-engineering/taxi_rides_ny
# 3. Create `profiles.yml` in `~/.dbt/`
# 4. Test the connection
dbt debug
# 5. Build the project
dbt build --target prod
云端开发(dbt Cloud + BigQuery)
优点: 强大,团队协作,调度器
缺点: 需要 GCP 账户(提供免费层)
- 创建一个 dbt Cloud 账户(免费)。
- 将其连接到你的 BigQuery 项目。
- 在 dbt Cloud IDE 中克隆仓库。
- 运行:
dbt build --target prod
常见问题排查 🔍
“未找到配置文件”
- 验证
dbt_project.yml中的profile名称与profiles.yml中的名称一致。 - 确保
profiles.yml位于~/.dbt/目录下。
“未找到来源”
- 检查
sources.yml中的数据库/模式名称。 - 确认数据已加载到数据仓库。
- 查找
ref()调用中的拼写错误,并确保被引用的模型存在。
可选的内存调优(profiles.yml):
settings:
memory_limit: '2GB'
关键概念
- Analytics Engineering 将数据工程和数据分析连接起来。
- dbt 将软件工程的最佳实践引入 SQL 转换。
- Dimensional modeling 将数据组织为 facts(事件)和 dimensions(属性)。
- 三层结构:staging(原始副本)、intermediate(转换层)、marts(最终可消费表)。
ref()和source()是构建模型依赖的主要函数。- Testing 确保数据质量——使用
unique、not_null、accepted_values、relationships。 - 文档由 YAML 描述自动生成。
dbt build按依赖顺序运行并测试所有内容。
附加资源 📚
- dbt Documentation
- dbt Fundamentals Course (free)
- SQL 窗口函数速查
- dbt 社区 Slack
建模愉快! 🚀