dbt 1.x 系の安定挙動に基づき、run・test・build・compile の違いを、試験の出題傾向と実務の観点で最短で理解できるよう整理します。
特に、build が umbrella コマンドとして seed・model・snapshot と test を DAG 順にまとめて実行する点、compile は SQL を生成するだけで DB を変更しない点が鍵です。
dbt run はモデルをビルドし、dbt test はテストを実行します。dbt build は seed・model・snapshot をビルドし、対応するテストをノードごとに後続で走らせる包括コマンドです。dbt compile は Jinja/refs を解決した SQL を生成するだけで、データベースには触れません。
試験・実務ともに重要なのは「何が実行され」「どの順序で」「副作用が何か」を明確にすることです。以下の比較表と図で、役割と実行パターンを一度に掴みます。
| コマンド | 実行対象 | テスト実行 | 主な副作用 |
|---|---|---|---|
| run | model・seed・snapshot(選択子に依存) | しない | テーブル/ビューの作成・更新 |
| test | generic/singular test | する(テストのみ) | 失敗行の格納(store_failures有効時) |
| build | seed・model・snapshot + 紐づくtest | する(ノード直後) | ビルドと検証を一括で再現 |
| compile | 全ノードのSQLレンダリング | しない | target/compiled配下のSQL生成 |
主要コマンドとDAG実行の関係
sources --> seeds --> models --> tests
| ^
v |
snapshots ----+
Legend:
- run: seeds/models/snapshots のみ実行(testsは含まない)
- test: tests のみ実行
- build: seeds -> (models/snapshots) -> tests の順で包括実行
- compile: 実行なし、SQL生成のみ最短の使い分け例
## 開発でモデルだけ動かす
$ dbt run --select my_model+
## テストだけ流す
$ dbt test --select tag:quality
## CIで一括(変更影響範囲のみ)
$ dbt build --select state:modified+ --defer --state targetdbt run はモデル(および選択に応じた seed/snapshot)をDAG順に実行します。テストは走らないため、品質検証が必要なら別途 test または build を組み合わせます。
増分モデルは materialized='incremental' のロジックに従い差分更新します。全件やり直したい場合は --full-refresh を使います。
| シナリオ | 推奨コマンド例 | 注意点 |
|---|---|---|
| 依存含めて部分ビルド | dbt run --select my_model+ | 上流/下流の向き(+の位置)に注意 |
| 全件作り直し | dbt run --full-refresh --select tag:fact | 増分テーブルが再作成される |
| 特定タグを除外 | dbt run --select tag:mart --exclude tag:heavy | 選択と除外は順序を意識 |
run の実行イメージ
seed_a model_b(ephemeral)
\ |
--> model_c (incremental)
run: seed_a -> model_c(model_bはインライン展開、testsは実行しない)選択子の具体例
# 依存先も含めビルド
$ dbt run --select my_model+
# 上流(親)も含める
$ dbt run --select +my_model
# フォルダ単位
$ dbt run --select models/marts/
# タグで除外
$ dbt run --select tag:daily --exclude tag:expensivedbt test は generic(not_null、unique 等)と singular(任意のSQLで記述)を実行します。基本ルールは「テストクエリが0行なら成功、1行以上返せば失敗」です。
失敗行を後で調査したい場合は store_failures を有効化します。警告として扱いたいチェックには severity: warn を付与できます。
| テスト種別 | 定義場所/方法 | 成功条件 |
|---|---|---|
| generic | models/schema.yml(not_null, unique, relationships等) | 0行 |
| singular | tests/xxx.sql(任意のSELECT) | 0行 |
test の依存関係
model_x --> test_not_null_model_x.col1
model_x --> test_unique_model_x.col2
テストは対象ノードに依存し、dbt test はテストノードのみ実行するschema.yml の例(generic)
version: 2
models:
- name: fct_orders
columns:
- name: order_id
tests:
- not_null
- unique
- name: customer_id
tests:
- relationships:
to: ref('dim_customers')
field: customer_id
severity: warn
config:
materialized: incremental
# singular(tests/late_orders.sql)
-- 0行で成功
select *
from {{ ref('fct_orders') }}
where order_date > current_date + interval '1 day'dbt build は seed・model・snapshot をDAG順にビルドし、各ノードに紐づくテストを続けて実行します。これにより、壊れた変更を依存先に波及させる前に検出できます。
変更影響のみを素早く検証するには state:modified 選択子と --defer を組み合わせ、未変更の依存を本番オブジェクトに委譲します。source freshness は別コマンド(dbt source freshness)である点に注意します。
| 目的 | build での書き方 | run/test を分離した場合の等価例 |
|---|---|---|
| 全体を一括検証 | dbt build | dbt seed && dbt run && dbt snapshot && dbt test |
| 変更影響のみCI | dbt build --select state:modified+ --defer --state target | dbt run --select state:modified+ && dbt test --select state:modified+ |
build の流れ(ノード単位)
[seed_s] -> (test_seed_s)
| \
v X(seedにはgeneric testがなければスキップ)
[model_m] -> test_model_m_*
|
v
[snapshot_n] -> test_snapshot_n_*CI向けスリムビルド例
# 直近のmanifest.jsonを用いた state 選択(例)
$ dbt build \
--select state:modified+ \
--defer \
--state target \
--profiles-dir . \
--target cidbt compile は Jinja、ref、source、変数、マクロを解決し、各ノードの SQL を target/compiled 配下に生成します。データベースに対する実行や変更は行いません。
実行前に生成SQLを確認できるため、レビューや静的解析に向いています。解析のみが目的なら parse もありますが、compile は最終SQLを出力する点が実務で便利です。
| 用途 | 得られる成果物 | エラー例 |
|---|---|---|
| PR前レビュー | 最終SQLファイル | 未定義ref/source、Jinja構文エラー |
| 静的解析/リンティング | ディレクトリツリー一式 | マクロ引数不整合、未解決変数 |
compile の生成物
project/
models/
macros/
...
|
v
target/compiled/project/
models/...
snapshots/...
tests/...
(DBへの実行は発生しない)生成SQLのパスと確認
# コンパイルのみ
$ dbt compile
# 例: compiled SQL を開く(モデル fct_orders)
$ sed -n '1,80p' target/compiled/<project>/models/marts/fct_orders.sql選択子は “どのノードを対象にするか” を厳密に制御します。+ は親/子の依存を含める演算子で、左側の + は上流(親)、右側の + は下流(子)を表します。
build は選択したノードに紐づくテストを自動で含めますが、run は含めない点が出題の常連です。resource type や tag、path を組み合わせて現実的な粒度に調整します。
| 式 | 含まれるノード | 主な用途 |
|---|---|---|
| +orders | orders とその親(上流) | 上流から再計算して整合性確保 |
| orders+ | orders とその子(下流) | 影響範囲の下流検証 |
| model:stg_* tag:pii | stg_で始まるモデル かつ PIIタグ | データクラス分けの部分実行 |
依存選択の直感図
src --> stg_orders --> int_orders --> marts_orders
^ ^ ^
+stg_orders +int_orders +marts_orders
my_model+ は右方向(子)に広がる組み合わせ例
# 親と自ノードのみ
$ dbt build --select +stg_orders --defer --state target
# 変更分の下流のみ
$ dbt build --select state:modified+ --defer --state target
# PIIを除外
$ dbt run --select tag:daily --exclude tag:piiAnalytics Engineer
問題 1
PRで一部モデルのみ更新。未変更の依存は上位環境の既存オブジェクトを参照し、変更部分とその下流だけをビルド・テストしたい。最短の1コマンドはどれか?
正解: A
build は選択したノードの seed/model/snapshot をDAG順に実行し、直後にテストも走らせる包括コマンド。state:modified+ で変更とその下流に限定し、--defer と --state で未変更依存を上位環境に委譲できる。run はテストを含まないため1コマンドで要件を満たさない。compile は実行なし、test 単体ではビルドしない。
run と build の一番の違いは?
run はモデル等のビルドのみでテストは含みません。build は seed・model・snapshot のビルドに加え、各ノードに紐づくテストを直後に実行します。CIや本番前検証は build が既定値になります。
compile はデータベース接続や変更を行いますか?
いいえ。compile はJinjaやrefの解決とSQL生成のみを行い、DBへの実行や変更は行いません。生成物は target/compiled 配下に出力され、レビューや静的解析に使えます。
source freshness は build に含まれますか?
含まれません。freshness チェックは dbt source freshness で個別に実行します。build は seed・model・snapshot とテストを対象にします。
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)、設定優先度...