dbt Connector

更新时间:
复制 MD 格式

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)

目前支持以下参数:

字段名

描述

默认值

type

指定数据库连接类型。

MaxCompute 连接必须设置为"maxcompute"。

“maxcompute”

project

MaxCompute 项目名称。

必填(无默认值)

endpoint

连接 MaxCompute 的终端节点 URL。

必填(无默认值)

schema

模型在 MaxCompute 中使用的命名空间(模式)。

必填(无默认值)

auth_type

访问 MaxCompute 的认证类型。

“access_key”

access_key_id

用于 MaxCompute 认证的访问密钥 ID。

必填(无默认值)

access_key_secret

用于 MaxCompute 认证的访问密钥 Secret。

必填(无默认值)

其他认证类型,例如 STS(Security Token Service),具体配置请参考dbt-maxcompute repository。

运行dbt模型

dbt 新手可参考dbt-maxcompute repository ,也可以访问 dbt 官方文档,但需要针对 MaxCompute 进行额外适配。

功能说明及使用示例

dbt标准能力

dbt提供以下功能帮助用户编写反映核心业务逻辑的模型,详情请参见能力介绍。

功能

描述

生成持久化对象(如表或视图)

对于每个模型,可轻松配置其物化策略。物化策略代表了模型的构建方式(例如生成表或视图)。dbt 会自动生成底层的 SQL 代码,将查询结果持久化为数据仓库中的对象(如创建新表或更新现有表)。

使用代码编译器

SQL 文件可以包含 Jinja(一种轻量级模板语言)。在 SQL 中使用 Jinja 可以在查询中引入控制结构(如条件判断if/else和循环for),并借助宏(Macros)复用重复的 SQL 代码。

确定模型执行顺序

在数据转换过程中,分阶段处理通常更合理。dbt通过ref()函数提供了一种按阶段实现转换的机制。无需直接查询数据仓库中的现有表或视图,而是可以直接引用另一个模型(例如上游模型),dbt 会自动根据依赖关系确定执行顺序。

生成和管理项目文档

在dbt Cloud中,可以在运行dbt项目时自动生成文档。dbt 提供了一种机制,允许编写、版本控制并共享模型文档。支持为每个模型和字段编写纯文本或Markdown格式描述。

测试模型数据完整性

测试通过断言模型生成的结果,来提高每个模型中SQL的数据完整性。可以通过单击按钮或使用dbt Cloud IDE命令栏,一键构建、测试和运行项目。

管理包

dbt 内置了包管理器,允许分析师使用和发布公共或私有仓库的 dbt 代码,并支持其他用户引用这些包。通过包管理,团队可以共享、复用和维护标准化的模型、宏或测试逻辑。

加载种子文件

在分析过程中,经常需要将原始值映射为更易读的值(例如将国家代码转换为国家名称),或用静态数据或不经常变化的数据丰富原始数据。这些数据源被称为种子文件,可以保存为项目中的CSV文件,并通过seed命令加载到数据仓库。

数据快照

数据源中的记录通常是可变的,会随时间变化。若要在分析中重建历史值,这可能带来挑战。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中示例

  1. 将 CSV 文件放置在seeds/目录中,文件扩展名为.csv,例如seeds/country_codes.csv。

    country_code,country_name
    US,United States
    CA,Canada
    GB,United Kingdom
    ...
  2. 运行dbt seed命令,在数据仓库的目标模式(schema)中创建一个名为country_codes的新表。

    image.png

  3. 在模型中引用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 的依赖关系图如下:

image.png

步骤三:测试与文档化源
  • 为源添加数据测试。

  • 为源添加描述,这些描述会作为文档站点的一部分生成。

模型中可配置属性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 freshness

dbt 会根据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

配置项说明:

配置项

描述

是否必须

示例

database

指定快照存储的数据库

否

analytics

schema

指定快照存储的模式(schema)

否

snapshots

alias

快照表的别名

否

custom_snapshot_name

strategy

快照策略类型,可选 timestamp(时间戳)或 check(检查列变化)

是

timestamp

unique_key

唯一键列或表达式(如 [order_id, product_id])

是

id

check_cols

在 check 策略下,需比较的列列表(或 all 表示所有列)

是(仅 check策略)

["status", "is_cancelled"]

updated_at

在 timestamp 策略下,记录最后更新时间的字段

是(仅 timestamp策略)

updated_at

dbt_valid_to_current

当前快照记录的 dbt_valid_to 字段的自定义值(如未来日期)

否

"to_date('9999-12-31')"

hard_deletes

硬删除处理方式(默认 ignore)

否

new_record

创建快照

  1. 创建配置文件:在snapshots目录下创建 YAML 文件,如snapshots/orders_snapshot.yml。

  2. 定义快照逻辑:通常直接选择源表数据(如通过临时模型预处理数据):

    -- models/ephemeral_orders.sql(临时模型)
    {{ config(materialized='ephemeral') }}
    SELECT * FROM {{ source('jaffle_shop', 'orders') }}
  3. 运行快照命令:

    $ 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),包含以下元数据字段:

元字段

含义

dbt_valid_from

该快照行生效的起始时间。

dbt_valid_to

该快照行失效时间(当前有效记录默认为 NULL 或配置值)。

dbt_scd_id

快照行的唯一标识符(内部使用)。

dbt_updated_at

源记录更新时间(内部使用)。

dbt_is_deleted

记录是否被删除(new_record 策略下启用)。

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

此命令负责通过以下步骤为项目生成文档网站:

  1. 将网站的index.html文件复制到target/目录。

  2. 编译项目中的资源,使其编译后的代码包含在manifest.json中。

  3. 对数据库元数据运行查询,生成包含项目模型生成的表和视图元数据的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 及更早版本中,默认主机为 ""。