MaxCompute dbt connector是由阿里云MaxCompute向开源社区贡献的dbt兼容版本,便于用户使用 dbt(数据构建工具)连接阿里云 MaxCompute 并扩展 dbt,MaxCompute Adapter基本支持dbt Core提供的所有功能。
dbt(data build tool)是一款专为数据仓库开发设计的开源工具,旨在通过模块化、版本控制和自动化流程,提升数据转换与分析代码的开发效率和质量。它支持将SQL逻辑转化为可维护的数据管道,兼容多个主流云数据平台。
核心功能
代码化数据转换
将ETL流程以代码形式管理,支持版本控制、CI/CD集成及团队协作。
模块化与可复用性
通过模型(Model)和宏(Macro)实现逻辑复用,降低重复开发成本。
数据测试与文档化
内置数据质量校验工具,并自动生成文档,确保数据管道的可靠性与透明性。
环境隔离
支持开发、测试、生产等多环境配置,保障生产数据安全。
适用场景
多云数据仓库对接
大规模数据分析涉及不同云上的数据仓库,需要通过统一方式完成对接和数据转换。
数据开发流程工程化
数据转换逻辑需要持续迭代,通过版本控制管理变更,并通过自动化测试验证数据质量。
操作步骤
安装插件
# we use conda and python 3.9 for this example
conda create --name dbt-maxcompute-example python=3.9
conda activate dbt-maxcompute-example
# current dbt-maxcompute version is 1.9
pip install dbt-core==1.9.4
pip install dbt-maxcompute参数配置
创建并配置profiles.yml文件
在用户主目录下名为
.dbt的文件夹中创建一个名为profiles.yml的文件。将以下内容复制并粘贴到新创建的
profiles.yml文件中。请确保更新标注需要修改的值。jaffle_shop: # this needs to match the profile in your dbt_project.yml file target: dev outputs: dev: type: maxcompute project: dbt-example # Replace this with your project name schema: default # Replace this with schema name, e.g. dbt_bilbo endpoint: http://service.cn-shanghai.maxcompute.aliyun.com/api # Replace this with your maxcompute endpoint auth_type: access_key access_key_id: XXX # Replace this with your accessId(ak) access_key_secret: XXX # Replace this with your accessKey(sk)
目前支持以下参数:
字段名 | 描述 | 默认值 |
| 指定数据库连接类型。 MaxCompute 连接必须设置为 | “maxcompute” |
| MaxCompute 项目名称。 | 必填(无默认值) |
| 连接 MaxCompute 的终端节点 URL。 | 必填(无默认值) |
| 模型在 MaxCompute 中使用的命名空间(模式)。 | 必填(无默认值) |
| 访问 MaxCompute 的认证类型。 | “access_key” |
| 用于 MaxCompute 认证的访问密钥 ID。 | 必填(无默认值) |
| 用于 MaxCompute 认证的访问密钥 Secret。 | 必填(无默认值) |
其他认证类型,例如 STS(Security Token Service),具体配置请参考dbt-maxcompute repository。
运行dbt模型
dbt 新手可参考dbt-maxcompute repository ,也可以访问 dbt 官方文档,但需要针对 MaxCompute 进行额外适配。
功能说明及使用示例
dbt标准能力
dbt提供以下功能帮助用户编写反映核心业务逻辑的模型,详情请参见能力介绍。
功能 | 描述 |
生成持久化对象(如表或视图) | 对于每个模型,可轻松配置其物化策略。物化策略代表了模型的构建方式(例如生成表或视图)。dbt 会自动生成底层的 SQL 代码,将查询结果持久化为数据仓库中的对象(如创建新表或更新现有表)。 |
使用代码编译器 | SQL 文件可以包含 Jinja(一种轻量级模板语言)。在 SQL 中使用 Jinja 可以在查询中引入控制结构(如条件判断 |
确定模型执行顺序 | 在数据转换过程中,分阶段处理通常更合理。dbt通过 |
生成和管理项目文档 | 在dbt Cloud中,可以在运行dbt项目时自动生成文档。dbt 提供了一种机制,允许编写、版本控制并共享模型文档。支持为每个模型和字段编写纯文本或Markdown格式描述。 |
测试模型数据完整性 | 测试通过断言模型生成的结果,来提高每个模型中SQL的数据完整性。可以通过单击按钮或使用dbt Cloud IDE命令栏,一键构建、测试和运行项目。 |
管理包 | dbt 内置了包管理器,允许分析师使用和发布公共或私有仓库的 dbt 代码,并支持其他用户引用这些包。通过包管理,团队可以共享、复用和维护标准化的模型、宏或测试逻辑。 |
加载种子文件 | 在分析过程中,经常需要将原始值映射为更易读的值(例如将国家代码转换为国家名称),或用静态数据或不经常变化的数据丰富原始数据。这些数据源被称为种子文件,可以保存为项目中的CSV文件,并通过 |
数据快照 | 数据源中的记录通常是可变的,会随时间变化。若要在分析中重建历史值,这可能带来挑战。dbt 提供了通过快照功能捕获某一时间点原始数据状态的机制。 |
Model
dbt提供多种功能帮助开发者编写适应业务需求变化的select查询模型,以提高查询效率。当执行dbt run时,该模型会直接在数据仓库内部转换数据,无需将数据移出仓库。另外,dbt还支持除SQL外的其他语言,自 v1.3 版本起,dbt Core 和 dbt Cloud 开始支持 Python 模型。Python 模型适用于以下场景:
训练或部署数据科学模型(如机器学习)。
复杂数据转换(如文本处理、图计算)。
使用特定 Python 库(例如
dateutil库解析日期)。
在现代工作流中,dbt 的顶层结构是项目。一个项目包含:
项目配置文件(
.yml文件),定义项目元数据和全局设置。模型文件(
.sql或.py文件),定义数据转换逻辑。
项目配置文件告知 dbt 如何构建数据集,而模型则指定具体的数据转换规则。且可以通过模型的互相引用提升数据转换的效率。详情请参见Model文档。
Seed
种子(Seeds)是位于 dbt 项目中的 CSV 文件(通常存放在seeds目录),可通过运行dbt seed命令将其加载到数据仓库中。种子文件可通过与模型相同的ref函数在下游模型中引用。由于这些 CSV 文件存储在 dbt 仓库中,因此它们可以被版本控制和代码审查。种子最适合存储静态数据(如枚举值、映射表),这些数据很少变化。详情请参见Seeds文档。
示例
添加seed file到dbt project中示例
将 CSV 文件放置在
seeds/目录中,文件扩展名为.csv,例如seeds/country_codes.csv。country_code,country_name US,United States CA,Canada GB,United Kingdom ...运行
dbt seed命令,在数据仓库的目标模式(schema)中创建一个名为country_codes的新表。
在模型中引用seed文件
models/orders.sql-- This refers to the table created from seeds/country_codes.csv SELECT * FROM {{ ref('country_codes') }}
Source
数据源(Sources)用于在 dbt 项目中声明和描述原始数据表。这些表的数据由提取和加载工具写入数据仓库。将这些表声明为数据源后,可以:
使用
source()函数引用源表进行查询,并建立源表与下游模型之间的数据血缘关系。通过数据测试检查源数据是否符合预期。
检查源数据的新鲜度,判断数据是否及时更新(时效性)。
详情请见Sources文档。
操作步骤
步骤一:声明源
源在以sources:键嵌套的.yml文件中定义。models/<filename>.yml
version: 2
sources:
- name: jaffle_shop
database: raw
schema: jaffle_shop
tables:
- name: orders
- name: customers
- name: stripe
tables:
- name: payments默认情况下,schema的名称与name相同。如果需要使用不同于现有模式的名称,需显式指定schema。
步骤二:从源表中选择数据
声明源后,可通过{{ source() }}函数在模型中引用它:
models/orders.sql
SELECT
...
FROM {{ source('jaffle_shop', 'orders') }}
LEFT JOIN {{ source('jaffle_shop', 'customers') }} USING (customer_id)dbt 会将其编译为完整的表名
SELECT
...
FROM raw.jaffle_shop.orders
LEFT JOIN raw.jaffle_shop.customers USING (customer_id)使用{{ source() }}函数会创建模型与源表之间的依赖关系。模型 orders 与源表 jaffle_shop.customers、jaffle_shop.orders 的依赖关系图如下:

步骤三:测试与文档化源
为源添加数据测试。
为源添加描述,这些描述会作为文档站点的一部分生成。
模型中可配置属性models/<filename>.yml
version: 2
sources:
- name: jaffle_shop
description: This is a replica of the Postgres database used by our app
tables:
- name: orders
description: >
One record per order. Includes cancelled and deleted orders.
columns:
- name: id
description: Primary key of the orders table
tests:
- unique
- not_null
- name: status
description: Note that the status can change over time
- name: ...
- name: ...源数据新鲜度检测
通过添加少量额外配置,dbt 可以选择性地检测源表数据的新鲜度(Freshness)。这一功能有助于判断数据流水线是否处于健康状态,是定义数据仓库服务等级协议(SLA)的关键组成部分。
步骤一:声明数据新鲜度
在源配置models/<filename>.yml中添加freshness和loaded_at_field:
version: 2
sources:
- name: jaffle_shop
database: raw
freshness: # 默认新鲜度阈值
warn_after: {count: 12, period: hour}
error_after: {count: 24, period: hour}
loaded_at_field: _etl_loaded_at
tables:
- name: orders
freshness: # 更严格的时间阈值
warn_after: {count: 6, period: hour}
error_after: {count: 12, period: hour}
- name: customers # 继承父级配置
- name: product_skus
freshness: null # 不检查此表的新鲜度步骤二:验证数据新鲜度
运行dbt source freshness命令检测源数据的新鲜度:
$ dbt source freshnessdbt 会根据freshness配置生成查询:
SELECT
MAX(_etl_loaded_at) AS max_loaded_at,
CONVERT_TIMEZONE('UTC', CURRENT_TIMESTAMP()) AS calculated_at
FROM raw.jaffle_shop.orders若检测到数据未达到新鲜度阈值,会触发警告或错误。
Snapshots
当源表通过更新覆盖原有字段值时,表中仅保留当前状态,无法直接查询历史状态。dbt 快照用于保存源表中记录的历史版本,以支持历史数据查询与分析。详情请参见Snapshots文档。
dbt 快照采用缓慢变化维度类型 2(Slowly Changing Dimension Type 2,SCD Type 2)的方式记录变化:检测到记录变更时,保留旧版本并新增一个版本,通过 dbt_valid_from 和 dbt_valid_to 标识各版本的有效时间范围。
例如,orders 表中的 status 字段表示订单状态。订单发货前,状态为 pending:
id | status | updated_at |
1 | pending | 2024-01-01 |
订单发货后,status 更新为 shipped,覆盖原有的 pending 值:
id | status | updated_at |
1 | shipped | 2024-01-02 |
如果快照在更新前后分别捕获了这两个状态,快照表将保留对应的两个记录版本及其有效时间范围:
id | status | updated_at | dbt_valid_from | dbt_valid_to |
1 | pending | 2024-01-01 | 2024-01-01 | 2024-01-02 |
1 | shipped | 2024-01-02 | 2024-01-02 | null |
配置快照
在 YAML 文件中定义快照的配置,告知 dbt 如何检测记录变化。配置文件应与模型并列存放,或置于snapshots目录中。
snapshots:
- name: orders_snapshot
relation: source('jaffle_shop', 'orders') # 源表或模型引用
description: "订单状态变化快照"
config:
database: analytics
schema: snapshots
alias: your_custom_snapshot
strategy: timestamp # 策略类型:timestamp 或 check
unique_key: id # 唯一键列或表达式
check_cols: ["status"] # 仅在 check 策略时配置
updated_at: updated_at # 仅在 timestamp 策略时配置
dbt_valid_to_current: "to_date('9999-12-31')" # 自定义当前记录的 dbt_valid_to 值
snapshot_meta_column_names: {} # 元字段自定义名称
hard_deletes: ignore # 硬删除处理方式:ignore、invalidate、new_record配置项说明:
配置项 | 描述 | 是否必须 | 示例 |
| 指定快照存储的数据库 | 否 |
|
| 指定快照存储的模式(schema) | 否 |
|
| 快照表的别名 | 否 |
|
| 快照策略类型,可选 | 是 |
|
| 唯一键列或表达式(如 | 是 |
|
| 在 | 是(仅 |
|
| 在 | 是(仅 |
|
| 当前快照记录的 | 否 |
|
| 硬删除处理方式(默认 | 否 |
|
创建快照
创建配置文件:在
snapshots目录下创建 YAML 文件,如snapshots/orders_snapshot.yml。定义快照逻辑:通常直接选择源表数据(如通过临时模型预处理数据):
-- models/ephemeral_orders.sql(临时模型) {{ config(materialized='ephemeral') }} SELECT * FROM {{ source('jaffle_shop', 'orders') }}运行快照命令:
$ dbt snapshot Running with dbt=1.9.0 15:07:36 | 1 of 1 OK snapshot snapshots.orders_snapshot..........[SELECT 3 in 1.82s]
运行后,快照表会创建在指定路径(如analytics.snapshots.orders_snapshot),包含以下元数据字段:
元字段 | 含义 |
| 该快照行生效的起始时间。 |
| 该快照行失效时间(当前有效记录默认为 |
| 快照行的唯一标识符(内部使用)。 |
| 源记录更新时间(内部使用)。 |
| 记录是否被删除( |
Macro
宏属性可在任意properties.yml文件中声明。宏属性的特殊性在于,它们无法在dbt_project.yml文件或通过config()块进行配置。宏路径请参见macro-paths。
示例配置文件(macros/<文件名>.yml):
version: 2
macros:
- name: <宏名称>
description: <Markdown 格式描述>
docs:
show: true | false # 控制是否在文档中显示该宏
meta: {<字典>} # 自定义元数据(可选)
arguments:
- name: <参数名称>
type: <数据类型字符串>
description: <Markdown 格式描述>
- ... # 声明其他参数属性
- name: ... # 声明其他宏属性Docs
dbt docs包含两个受支持的子命令:generate和serve。详情请参见Docs文档。
dbt docs generate
此命令负责通过以下步骤为项目生成文档网站:
将网站的
index.html文件复制到target/目录。编译项目中的资源,使其编译后的代码包含在
manifest.json中。对数据库元数据运行查询,生成包含项目模型生成的表和视图元数据的
catalog.json文件(例如表的列信息和统计信息)。
示例:
dbt docs generate参数用法:
--select:限制包含在catalog.json中的节点。提供此标志时,步骤(3)仅针对所选节点运行,其他节点将被排除。步骤(2)不受影响。dbt docs generate --select +orders--no-compile:跳过重新编译。提供此标志时,dbt docs generate将跳过步骤(2)。dbt docs generate --no-compile--empty-catalog:跳过运行数据库查询以填充catalog.json。提供此标志时,dbt docs generate将跳过步骤(3)。dbt docs generate --empty-catalog--static:生成静态页面以便托管在云存储提供商上。catalog.json和manifest.json文件将被插入到index.html文件中,生成一个可通过邮件或文件共享应用轻松共享的单页。dbt docs generate --static
dbt docs serve
此命令在本地启动一个 Web 服务器(端口 8080),提供文档访问,并在默认浏览器中打开文档站点。Web 服务器基于target/目录运行。请确保在运行dbt docs serve之前先执行dbt docs generate,因为generate命令会生成serve依赖的元数据文件catalog。若catalog文件缺失,将触发错误提示。
适用场景:
当在本地使用 Cloud CLI 或 dbt Core 开发时使用此命令。dbt Cloud IDE 不支持此命令。
用法
dbt docs serve [--profiles-dir PROFILES_DIR]
[--profile PROFILE] [--target TARGET]
[--host HOST]
[--port PORT]
[--no-browser]参数说明:
--port:指定不同的端口。dbt docs serve --port 8001--host:指定不同的主机地址。dbt docs serve --host ""默认主机设置:
自版本 1.8.1 起,默认主机为
127.0.0.1。在版本 1.8.0 及更早版本中,默认主机为
""。