dbt の日常運用で最も手に取るパッケージのひとつが dbt_utils です。クロスウェアハウスで安定して動き、モデル記述を短く読みやすくします。
ここでは試験でも実務でも頻出のマクロに絞って、用途・落とし穴・最低限のスニペットをまとめます。公式ドキュメントの一般的で安定した使い方のみを扱います。
まずは全体像。試験の設問は「どのマクロを選ぶべきか」を問うことが多いので、ユースケースを軸に俯瞰します。
ここに挙げるマクロは、主要 DWH(Snowflake、BigQuery、Redshift、Databricks/Spark)で広く使われ、API も安定しています。
| マクロ | 典型用途 | 実務の要点 | 試験の観点 |
|---|---|---|---|
| generate_surrogate_key | 複数カラムから一意キーを生成 | トリミングと NULL を統一処理して安定ハッシュを作る | ワークハウス間の一貫性と NULL 耐性を選択理由にできるか |
| star | SELECT 列展開(除外・prefix/suffix) | スキーマ変動時の列メンテ負荷を下げる | ワイルドカードの安全な代替として説明できるか |
| union_relations | スキーマ差があるテーブルの UNION | 不足列を NULL 補完・順序そろえで失敗を防ぐ | 異なるカラム集合の統合に最適と判断できるか |
| date_spine | 日付・時間の連続行を生成 | 開始/終了境界のオフバイワンに注意 | カレンダーテーブルの作り方を選べるか |
| safe_divide | ゼロ割り回避の集計 | NULL/0 を安全に処理しダッシュボードの NaN を防ぐ | 堅牢な派生指標の作成を説明できるか |
| unique_combination_of_columns(テスト) | 複合一意の検証 | 業務キーの一貫性確保に直結 | どの粒度で一意性を担保すべきか判断できるか |
packages.yml への追加(前提)
packages:
- package: dbt-labs/dbt_utils
version: "+" # 安定版の範囲指定(プロジェクトの互換性に合わせる)dbt_utils はモデリングの反復作業を短縮し、スキーマ変化や DWH 差異に強い SQL を書く助けになります。特に Staging/Intermediate/Mart の各層で役割が明確です。
試験では、どの層でどのマクロを使うと保守性が高いか、という観点がよく問われます。
dbt モデル層と頻出マクロの対応
ref と Jinja によるマクロ呼び出しの基本形
select
{{ dbt_utils.star(from=ref('stg_orders'), except=['_ingested_at']) }}
from {{ ref('stg_orders') }}複数カラムの結合やディメンションの同定に必要なのが代理キーです。generate_surrogate_key はトリムや NULL を吸収して一貫性のあるハッシュ文字列を返します。
ベースの列を変更したらキーも変わるため、ディメンションの SCD 設計とあわせて使い方を固定化しておくと安全です。
典型スニペット(ディメンションの自然キーから代理キー)
with src as (
select * from {{ ref('stg_customers') }}
)
select
{{ dbt_utils.generate_surrogate_key([
'coalesce(country_code, \"\")',
'customer_id'
]) }} as customer_sk,
*
from src生ソースの列は増減や並び順変更が起こります。star は除外や接頭辞/接尾辞を指定して安全に列展開します。さらに複数テーブルを統合する際は union_relations が列不一致を自動で補完します。
試験では SELECT * の危険性と、star による制御可能な列展開の説明、そして UNION 前整形の手法が問われます。
複数ソースを UNION(列不一致を自動調整)
with a as (
select {{ dbt_utils.star(from=ref('stg_orders_us'), except=['_ingested_at']) }} from {{ ref('stg_orders_us') }}
), b as (
select {{ dbt_utils.star(from=ref('stg_orders_eu'), except=['_ingested_at']) }} from {{ ref('stg_orders_eu') }}
)
select * from {{ dbt_utils.union_relations(relations=[ref('stg_orders_us'), ref('stg_orders_eu')]) }}イベントが無い日もレポートに日付行を出したいとき、date_spine で連続系列を生成して左結合します。これにより稼働日での欠測が可視化されます。
開始・終了の境界と粒度を明示し、オフバイワンを避けます。終了日は通常、当日または翌日開始時刻にします。
日次スパインと売上の結合(ゼロ埋め)
with spine as (
select * from {{ dbt_utils.date_spine(
datepart='day',
start_date="cast('2021-01-01' as date)",
end_date="current_date"
) }}
), sales as (
select order_date::date as d, sum(amount) as revenue
from {{ ref('fct_orders') }}
group by 1
)
select s.date_day as d,
coalesce(sa.revenue, 0) as revenue
from spine s
left join sales sa on sa.d = s.date_dayモデルの品質担保は試験でも実務でも重要です。dbt_utils のテストマクロでビジネスキーの一意性を検証し、集計では safe_divide を用いてゼロ割りを回避します。
特に Looker や BI でゼロ割りエラーや NaN を発生させない実装は、ダッシュボード安定運用の基礎です。
YAML テストと安全な除算の例
# models/schema.yml
version: 2
models:
- name: dim_customer
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns: [customer_natural_key, effective_from]
-- models/mart/fct_kpi.sql
select
date_day,
{{ dbt_utils.safe_divide(sum(conversions), nullif(sum(sessions), 0)) }} as cr
from {{ ref('fct_sessions') }}
group by 1Analytics Engineer
問題 1
複数のソースから得た customer_id と country_code を結合し、DWH 間で一貫した代理キーを作成したい。NULL や前後空白のばらつきにも耐性を持たせるには、dbt_utils のどのマクロを使うべきか?
正解: A
generate_surrogate_key は複数カラムから安定したハッシュキーを生成し、NULL や空白のゆらぎを吸収する。star は列展開、union_relations は UNION 整形、safe_divide は数値演算用であり目的に合致しない。
dbt_utils のマクロは DWH ごとに動作が変わる心配はない?
主要マクロはアダプター・ディスパッチで DWH 差異を吸収します。例えば generate_surrogate_key は各エンジンの関数差を内部で扱います。ただし start_date/end_date のように SQL 文字列で渡す箇所(date_spine など)は、各 DWH が解釈できる式にする必要があります。
star は SELECT * と何が違う?
star は除外(except)や接頭辞/接尾辞(prefix/suffix)を指定でき、列の並びや命名衝突を制御できます。SELECT * のように予期しない新列が混入してクエリが壊れるリスクを抑えられます。
テストマクロ unique_combination_of_columns はいつ書くべき?
ディメンションの自然キーやファクトの業務上の一意粒度を定義したら同時に書くのが実務では安全です。CI の毎回実行で重複を即検知でき、下流の集計崩れを防ぎます。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
dbt Model の基礎: SQL で定義する変換の最小単位
Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...
dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点
dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...
dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点
dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...
dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト
Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....
dbt_project.yml の読み方:主要設定と命名を最短で掴む
dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...