現代資料分析仰賴自動化資料轉換,dbt Cloud 提供了簡化流程的方案。設定 dbt Cloud 作業,首先需明確命名,以便識別與管理。接著設定作業環境,包含佈署環境、dbt 版本和目標名稱。執行設定涵蓋超時、延遲選項以及檔案生成與來源更新檢查。觸發器設定提供排程、Webhooks 和 API 呼叫等啟動方式。執行作業後,dbt Cloud 提供執行歷史和概覽,方便監控狀態與詳細資訊。進階應用包含模型物化策略,如表格、檢視、短暫模型、增量模型、物化檢視和快照,可依據需求選擇。Jinja、宏和套件則可提升程式碼效率,避免重複。
在dbt Cloud中設定與執行作業的完整
在現代資料分析工程中,自動化資料轉換流程是至關重要的。dbt(Data Build Tool)提供了一個強大的解決方案,能夠幫助資料分析師、資料工程師和分析工程師簡化資料轉換的複雜性。本篇文章將探討如何在dbt Cloud中設定和執行作業,以實作自動化和高效的資料轉換。
設定dbt Cloud作業
要在dbt Cloud中設定一個新的作業,需要遵循以下步驟:
命名作業:首先,為你的作業命名。這是一個簡單但重要的步驟,因為它將幫助你識別和管理多個作業。
設定作業名稱
在dbt Cloud UI中,點選Deploy選單中的Jobs選項,然後點選Create New Job按鈕。為你的作業取一個描述性的名稱,如圖所示。
組態環境:接下來,你需要組態作業的環境。這包括選擇佈署環境、組態dbt版本、以及設定目標名稱。
環境組態詳解
- 佈署環境:指向你的佈署環境。
- dbt版本:繼承自佈署環境中定義的版本。
- 目標名稱:預設為
default,這允許你根據工作環境定義不同的條件。 - 執行緒:保持預設組態,這與
profiles.yml檔案中的設定相關。
執行設定:在這一部分,你可以組態作業的執行設定,包括超時設定、是否延遲到另一個執行、以及是否在執行時生成檔案和執行來源更新檢查。
執行設定詳解
此圖示呈現了執行設定的主要選項。設定
Run Timeout為0意味著dbt不會因為執行時間過長而終止作業。同時,選擇“Generate docs on run”和“Run source freshness”可以減少需要在Commands部分編寫的命令數量。觸發器設定:最後,你需要設定觸發器來決定如何啟動作業。dbt Cloud提供了三種觸發作業的方式:排程、Webhooks、以及API呼叫。
觸發器設定詳解
- 排程:你可以設定一個排程來定期執行作業。
- Webhooks:透過Webhooks來觸發作業。
- API呼叫:透過API呼叫來觸發作業。
@startuml skinparam backgroundColor #FEFEFE skinparam componentStyle rectangle
title dbt Cloud作業設定與執行完整
package “機器學習流程” { package “資料處理” { component [資料收集] as collect component [資料清洗] as clean component [特徵工程] as feature }
package "模型訓練" {
component [模型選擇] as select
component [超參數調優] as tune
component [交叉驗證] as cv
}
package "評估部署" {
component [模型評估] as eval
component [模型部署] as deploy
component [監控維護] as monitor
}
}
collect –> clean : 原始資料 clean –> feature : 乾淨資料 feature –> select : 特徵向量 select –> tune : 基礎模型 tune –> cv : 最佳參數 cv –> eval : 訓練模型 eval –> deploy : 驗證模型 deploy –> monitor : 生產模型
note right of feature 特徵工程包含:
- 特徵選擇
- 特徵轉換
- 降維處理 end note
note right of eval 評估指標:
- 準確率/召回率
- F1 Score
- AUC-ROC end note
@enduml
**此圖示**展示了觸發器的三種選項。在本例中,我們選擇了排程選項,並設定為每小時執行一次。
### 執行與監控作業
一旦你設定好了作業,就可以儲存並執行它。你可以選擇立即執行或等待排程觸發。dbt Cloud提供了詳細的執行歷史和執行概覽,讓你可以監控作業的狀態和執行的詳細資訊。
#### 執行概覽詳解
執行概覽提供了關於作業執行的關鍵資訊,包括:
- 作業執行的狀態
- 誰或什麼系統觸發了作業
- 與此作業執行相關聯的Git提交
- 生成的檔案和來源
- 作業執行的環境
此外,執行步驟詳細列出了在作業執行期間執行的所有命令,並允許你檢查每個獨立步驟的日誌。
## 深入探索 dbt 的進階主題
dbt 是一個專注於 ELT 流程中轉換(Transformation)環節的工具。僅憑藉 SQL 經驗,我們就能利用 dbt 開發出所有的分析程式碼。同時,在軟體工程的最佳實踐和標準下,如測試開發、自動佈署以及邊開發邊建立的檔案,都能被完美地整合進來。
本章中,我們將對 dbt 的探索提升到更進階和細微的層次。我們將深入研究 dbt 中多樣化的模型物化(Model Materializations)策略。除了傳統的檢視(Views)和表格(Tables),我們還會探索短暫模型(Ephemeral Models)、物化檢視(Materialized Views)、資料快照(Snapshots)以及增量模型(Incremental Models)的潛力,這些都能讓你擺脫頻繁、耗費資源的完整資料載入。
此外,我們還將透過 Jinja、宏(Macros)和套件(Packages)將你的分析程式碼提升到新的高度。我們的目標是讓你的程式碼函式庫變得更加高效,遵循 DRY(Don't Repeat Yourself)原則。學完本章後,你將具備提升分析工作流程所需的知識和工具,從而能夠更快、更精確地交付洞察結果。
### 模型物化策略
模型物化是 dbt 在資料平台上持久化模型的策略。在 dbt 中,物化可以透過減少即時計算查詢和檢視的需求來提高資料模型的效能和可擴充套件性。
dbt 支援多種物化型別,可以根據專案的需求和要求進行選擇。例如,你可能會使用增量物化來儲存只需增量更新的查詢結果。此外,你還可能會使用快照,它們類別似於 dbt 中的物化,但具有不同的特性。快照用於在特定的時間點儲存查詢或檢視的結果,但它們並不是 dbt 中的模型。它們被設計為非冪等的,這使得它們與 dbt 的其他方面有所不同。
#### 表格、檢視和短暫模型
我們已經使用檢視或表格物化來實作我們的模型。本章旨在探討這兩種型別的物化,並介紹短暫模型。首先,讓我們看一下圖 5-1,它展示了之前建立的 `dim_customers` 的當前沿襲。在這個使用案例中,我們將測試各種物化策略,特別是透過更改 `stg_jaffle_shop_customers.sql` 模型的物化型別。
##### 表格物化
在 dbt 中,表格是用於儲存和組織資料的結構,由行和列組成;每一行代表一條記錄或資料,而每一列代表資料的特定屬性或欄位。當你選擇這種物化型別時,內部實際上是引數化 dbt,將參照的模型物理地建立在你的資料平台上,資料儲存在磁碟上;因此,構建速度會比較慢。通常,這些物化用於下游的 `marts` 層,並且在處理大量資料和多個查詢需要快速回應時間時推薦使用。
要測試表格物化,可以更改你的 YAML 檔案 `_jaffle_shop_models.yml`,將 `stg_jaffle_shop_customers` 模型的物化設定為 `table`。執行你的程式碼後,結果應該與 BigQuery 中的圖 5-2 類別似。
```sql
-- 示例程式碼:將 stg_jaffle_shop_customers 模型的物化設定為 table
models:
- name: stg_jaffle_shop_customers
config:
materialized: table
內容解密:
- 將模型的物化設定為
table,會使 dbt 將模型物理地儲存在資料平台上。 - 這種方式適合處理大量資料並需要快速查詢回應的場景。
- 但由於資料儲存在磁碟上,初次構建可能會比較慢。
檢視物化
檢視是透過從一個或多個上游模型中選擇和組合資料而建立的虛擬表格。檢視本身不儲存任何資料,而是在存取時從底層表格中檢索資料。通常,我們會在 dbt 中使用檢視來簡化複雜的查詢並促進整體的轉換過程,或者透過隱藏特定列或行資料來提供安全性。當我們將模型設定為檢視時,它將在你的資料平台上構建為檢視。實際上儲存的是查詢本身,因此只有在執行時才會捕捉資料並實施轉換,這可能會導致查詢回應時間變慢。
要測試檢視的使用,可以更改你的 YAML 檔案 _jaffle_shop_models.yml,將 stg_jaffle_shop_customers 模型的物化設定為 view。再次執行你的程式碼,結果應該與 BigQuery 中的圖 5-3 類別似。
-- 示例程式碼:將 stg_jaffle_shop_customers 模型的物化設定為 view
models:
- name: stg_jaffle_shop_customers
config:
materialized: view
內容解密:
- 將模型的物化設定為
view,會使 dbt 將模型建立為虛擬表格。 - 適合用於簡化複雜查詢或提供資料安全性的場景。
- 但由於每次查詢都需要重新計算,可能會導致查詢回應時間變慢。
短暫模型
dbt 即時構建這些臨時資料模型,而不是將它們持久化在資料函式庫中。最適合用於不需要永久儲存資料的輕量級資料操作或分析任務。當採用這種策略時,必須記住 dbt 會將其解釋為下游模型中的 CTEs(Common Table Expressions),這也可能增加這些模型的整體構建時間。此外,如果過度使用短暫模型,由於無法直接在資料平台中查詢它們,因此可能會增加除錯程式碼的複雜性。
要測試短暫模型,可以更改你的 YAML 檔案 _jaffle_shop_models.yml,將 stg_jaffle_shop_customers 模型的物化設定為 ephemeral。由於在這種情況下,你不會在資料平台中有實際的物化,可以檢視 dim_product 編譯後的程式碼。圖 5-4 展示了使用檢視和短暫模型的 stg_jaffle_shop_customers 模型編譯後的 dim_customer 程式碼之間的差異。
-- 示例程式碼:將 stg_jaffle_shop_customers 模型的物化設定為 ephemeral
models:
- name: stg_jaffle_shop_customers
config:
materialized: ephemeral
內容解密:
- 將模型的物化設定為
ephemeral,會使 dbt 即時構建臨時資料模型。 - 適合用於輕量級資料操作或分析任務。
- 但需要注意,它會被解釋為 CTEs,可能增加下游模型的構建時間,並增加除錯複雜性。
增量模型
在 dbt 專案中,增量模型被設計為僅處理新增或變更的資料,而不是來源中的所有資料。這些模型可以用於提高資料管道的效率和速度,尤其是在處理頻繁更新的大型資料集時。
要測試增量模型,首先需要在模型的 YAML 檔案中進行組態,將所需的模型設定為增量。我們將使用已經建立的模型 stg_jaffle_shop_orders 作為測試案例。檢視其 YAML 檔案 _jaffle_shop_models,我們發現它被物化為檢視。由於我們希望使其成為增量模型,因此更改很簡單,但我們還會嵌入額外的功能,例如 incremental_type。
-- 示例程式碼:將 stg_jaffle_shop_orders 模型的物化設定為 incremental
models:
- name: stg_jaffle_shop_orders
config:
materialized: incremental
incremental_type: append
內容解密:
- 將模型的物化設定為
incremental,會使 dbt 僅處理新增或變更的資料。 - 這種方式可以提高資料管道的效率和速度,尤其是在處理大型資料集時。
- 可以透過組態
incremental_type來控制增量模型的行為,例如追加(append)或替換(replace)。
增量模型(Incremental Models)與其組態最佳化
增量模型是資料處理管線最佳化中的關鍵技術,能夠顯著提升資料處理效率並降低計算成本。在dbt(Data Build Tool)中,增量模型透過特定的組態實作高效的資料載入與更新。
YAML檔案組態增量模型
首先,我們需要在YAML檔案中定義模型的物化型別為增量模型,並組態相關的最佳化引數。以下是一個範例組態:
version: 2
models:
- name: stg_jaffle_shop_orders
config:
materialized: incremental
incremental_strategy: merge
unique_key: order_id
組態解密:
materialized: incremental:將模型組態為增量模型,這是增量模型的核心組態。incremental_strategy: merge:定義增量策略為合併(merge),這使得每次增量執行時,新資料會根據指定的唯一鍵(unique key)與現有資料進行合併。unique_key: order_id:指定order_id為唯一鍵,用於識別資料是否需要更新或新增。
增量模型的程式碼實作
接下來,我們需要在模型的SQL程式碼中加入邏輯,以使其支援增量載入。以下是一個範例:
select
id as order_id,
user_id as customer_id,
order_date,
status,
_etl_loaded_at
from {{ source('jaffle_shop', 'orders') }}
{% if is_incremental() %}
where _etl_loaded_at >= (select max(_etl_loaded_at) from {{ this }} )
{% endif %}
內容解密:
is_incremental()巨集用於判斷目前執行的模型是否為增量模型。- 當
is_incremental()傳回true時,表示模型已組態為增量模式,並且不是全量重新整理(full-refresh)模式。 - 在
if程式區塊內,我們加入了一個where條件,過濾出_etl_loaded_at時間戳大於或等於目前表中最大_etl_loaded_at時間戳的資料列。 - 這確保了只有最新的資料才會被處理和載入到增量模型中。
增量模型的優勢
增量模型在最佳化資料管線方面發揮著重要作用,主要優勢包括:
- 成本效率:透過只處理變更的資料,顯著減少了所需的計算資源,從而降低成本。
- 即時性:確保dbt專案始終操作在最新的資料上,提高了分析結果的準確性和可靠性。
物化檢視(Materialized Views)
物化檢視是一種特殊的資料函式庫物件,它將查詢結果物化儲存為實體表格,並定期重新整理以反映底層資料的變化。物化檢視與dbt的增量模型有相似之處,都旨在最佳化資料存取效率。
組態物化檢視
在dbt中,可以透過修改模型的物化型別來使用物化檢視。以下是一個範例組態:
models:
- name: stg_jaffle_shop_customers
config:
materialized: materialized_view
對於Snowflake使用者,需要使用動態表格(dynamic table)的概念:
models:
- name: stg_jaffle_shop_customers
config:
materialized: dynamic_table
物化檢視與增量模型的比較
物化檢視和增量模型都旨在最佳化資料處理流程,但兩者之間存在一些差異:
- 物化檢視簡化了工作流程,將增量邏輯的管理交由資料平台處理,但可能會犧牲部分自定義控制。
- 增量模型則提供了更細粒度的控制,但需要手動管理增量策略。
快照(Snapshots)
快照是在特定時間點儲存的資料集副本,用於追蹤資料的歷史變化。在dbt中,快照透過應用Type 2緩慢變化維度(SCDs)來實作。
快照的應用場景
快照可以用於:
- 追蹤資料集的歷史變化。
- 測試和除錯,透過比較不同時間點的資料狀態來識別變化或差異。
利用dbt進行事務資料集的快照管理
在資料倉儲的建設中,事務資料集的管理是一項至關重要的任務。為了能夠追蹤狀態的轉變,我們需要保留資料的快照。在dbt中,這些快照是透過在.sql檔案中定義的snapshot區塊來實作的。
建立訂單狀態轉變快照
首先,在snapshots目錄下建立一個名為snap_order_status_transition.sql的檔案,並將Example 5-5中的程式碼複製到該檔案中。
Example 5-5: snap_order_status_transition.sql快照建立
{% snapshot orders_status_snapshot %}
{{
config(
target_schema='snapshots',
unique_key='id',
strategy='timestamp',
updated_at='_etl_loaded_at',
)
}}
select * from {{ source('jaffle_shop', 'orders') }}
{% endsnapshot %}
內容解密:
target_schema='snapshots': 指定dbt將快照表渲染到哪個schema中。這使得你可以將快照儲存在與生產環境不同的schema中,從而提供更大的靈活性。unique_key='id': 指定記錄的唯一鍵,通常是主鍵或具有唯一性的列。strategy='timestamp': 指定快照策略。這裡使用的是timestamp策略,這是推薦的策略,因為它對於新增列的擴充套件性更好。updated_at='_etl_loaded_at': 當使用timestamp策略時,需要指定用於跟蹤記錄更新時間的列。
執行快照並檢視輸出
在CLI中執行dbt snapshot命令來執行快照。成功後,在BigQuery中可以看到一個新的schema被建立,名為snapshots,並且包含了實際的快照表。
Figure 5-6: snap_order_status_transition快照表在BigQuery中的呈現
dbt建立了orders_status_snapshot快照表,並在資料平台中生成了四個額外的列:
dbt_scd_id: dbt內部使用的唯一鍵,為每個被快照的記錄生成。dbt_updated_at: 同樣是dbt內部使用,記錄了源記錄的updated_at時間戳。dbt_valid_from: 記錄了該快照行首次被插入的時間戳,可用於排序記錄的不同“版本”。dbt_valid_to: 記錄了該行被標記為無效的時間戳。如果記錄仍然是最新的有效記錄,則顯示為null。
利用Jinja進行動態SQL
Jinja是一種用於Python的範本語言,廣泛應用於Web開發。它允許你透過變數和表示式建立動態的HTML頁面。同樣,你也可以利用Jinja來提升dbt中的SQL程式碼。
Example 5-6: 使用Jinja與target name屬性
select *
from {{ ref('fct_orders') }}
-- 在開發環境中限制查詢的資料量
{% if target.name != 'prod' %}
where order_date > DATE_SUB(CURRENT_DATE(), INTERVAL 3 MONTH)
{% endif %}
內容解密:
{% ... %}: 用於陳述式,可以執行任何功能程式設計,如設定變數或開始for迴圈。target.name: dbt中的屬性,用於根據工作環境定義不同的行為。
利用Jinja生成動態SQL
透過Jinja,你可以建立更複雜的範本,以適應不同的資料和上下文。例如,你可以使用迴圈來迭代一列專案,並動態生成SQL程式碼,而不是手動逐一進行。
Example 5-7: 使用Jinja動態生成int_payment_type_amount_per_order模型
{# 宣告payment_type變數。如果出現新的支付型別,請在此新增 #}
{%- set payment_types = ['cash', 'credit'] -%}
with
payments as (
select * from {{ ref('stg_stripe_order_payments') }}
),
pivot_and_aggregate_payments_to_order_grain as (
select
order_id,
{% for payment_type in payment_types -%}
sum(
case
when payment_type = '{{ payment_type }}' and status = 'success'
then amount
else 0
end
) as {{ payment_type }}_amount,
{%- endfor %}
內容解密:
{%- set payment_types = ['cash', 'credit'] -%}: 宣告一個包含支付型別的列表變數。{% for payment_type in payment_types -%}: 使用迴圈迭代支付型別列表,動態生成SQL程式碼。
透過這種方式,你可以自動生成不同支付型別的金額指標,使模型更具擴充套件性和可維護性。