dbt

dbt run と dbt build の違いと使い分け(Analytics Engineer 試験と実務に効く要点)

2026-04-19
NicheeLab編集部

コマンドは知っていても、レビューや本番前の検証で迷いがちなのが run と build の使い分けです。実務では最短の反復、CI では信頼できる一貫性、試験では定義の正確さが問われます。

本稿は dbt の公式ドキュメントの挙動に沿って、違い・選び方・周辺機能(選択子、インクリメンタル、スナップショット、テスト)の連動をまとめます。

基本の違い:何が動くか、いつ止まるか

dbt run はモデルのみを対象に、選択子で指定したノードをコンパイルして実行します。テストは動きません。依存関係は実行順序に反映されますが、未選択の親モデルは自動では再実行されません(存在しない場合は参照エラー)。

dbt build は選択したスコープに含まれるシード、スナップショット、モデルを依存関係順に実行し、その後関連するテスト(スキーマ・データ)を実行します。つまり、1コマンドで「作る+確かめる」を完了させる統合フローです。

  • dbt run: モデルだけ。検証は別途 dbt test。
  • dbt build: シード/スナップショット/モデルの構築後、該当テストを自動実行。
  • どちらも選択子(-s/--select, -m エイリアス)でスコープを絞れる。
コマンド目的実行対象依存関係順序
dbt runモデルの実行models のみ参照順で実行。ただし未選択の親は基本実行しない
dbt build構築と検証の一括seeds, snapshots, models + testsDAG に従い一括実行

run と build の実行フロー(概念)

選択子で選ぶdbt rundbt buildmodels を実行(tests は別途)seeds/snapshots/models を DAG 順その後 tests を対象ノードのみ選択子で選び、run は models のみ、build は DAG 順で seeds/snapshots/models + テストまで

最小例:個別モデルと統合ビルド

# 個別モデルだけ(親は+で明示選択)
dbt run -s +stg_orders

# 選択範囲の構築とテストを一括
# 変更分とその下流、関連テストを対象
dbt build -s state:modified+

実行順序とテストの扱い(失敗時の挙動を含む)

dbt はDAGに基づき並列・順序制御します。build は対象ノードのビルド完了後に、そのノードに紐づくテストを実行します。未選択ノードのテストは走りません。

テスト失敗時は、そのテストが失敗として記録され、既定では他の独立ノードの実行は継続します(--fail-fast を付けると早期停止)。run はテストを実行しないため、失敗の検出は test 実行に依存します。

  • テストは node 完了後に実施。対象はスコープに含まれる資産に紐づいたもののみ。
  • --fail-fast で最初の失敗で停止。付けなければ可能な限り継続。
  • データテスト(singular)とスキーマテスト(generic)の両方が build で実行対象。
項目dbt rundbt build
テストの実行タイミングなし(別コマンド)各ノードの構築後
失敗時の既定挙動モデル失敗で当該枝は停止。他枝は継続し得る同左。テスト失敗は失敗として集計
停止を早めるオプション--fail-fast(run/test いずれにも適用可)--fail-fast

ノードとテストの実行シーケンス

A1) model 実行B2) model 実行 (ref: A)テスト t_B3) B に紐づくテストbuild 実行順: A → B → テスト t_B

スキーマテストとデータテストの例

# models/schema.yml(generic test 例)
models:
  - name: dim_customers
    columns:
      - name: customer_id
        tests:
          - not_null
          - unique

# tests/assert_positive_revenue.sql(singular test 例)
-- 失敗すると build は失敗として集計
select 1 where exists (
  select 1 from {{ ref('fct_revenue') }} where total_revenue < 0
);

# 実行
# スキーマ・データ両テストを fct_revenue, dim_customers に対して実行
dbt build -s dim_customers fct_revenue

選択子の使い分け:最小スコープで速く・安全に

run と build のどちらでも、何を対象にするかは選択子で決まります。+で親子を含める、tag: で属性選択、state: で変更影響範囲をとるのが基本です。

build の場合は選んだスコープに対しテストも自動で付随する点が差分です。未選択のノードに紐づくテストは実行されません。

  • +my_model は上流も含める、my_model+ は下流も含める、+my_model+ は両側を含める
  • state:modified+ は変更ノードとその下流(影響範囲)を対象にでき、CI で有用
  • resource_type:, tag:, path:, config.materialized: などで粒度を調整
選択子意味典型用途
+stg_ordersstg_orders とその上流参照先を含めて一気に確認
state:modified+変更ノードとその下流PR/CI の影響範囲テスト
tag:nightlytag が nightly の資産夜間バッチの対象限定

選択子によるスコープの違い

A -> B -> C

-s B      : [B]
-s +B     : [A, B]
-s B+     : [B, C]
-s +B+    : [A, B, C]

run と build で同じ選択子を使う

# 開発ループ(モデルだけ速く)
dbt run -s +stg_orders

# CI(影響範囲を構築&検証)
dbt build -s state:modified+ --defer --state target/manifest

インクリメンタル・スナップショットとの相性

インクリメンタルモデルは選択されたときに既定モードで差分反映され、--full-refresh で全再計算します。run でも build でも動作は同じです。

スナップショットは独立したノードで、ref されるとDAGに組み込まれます。build はスナップショットも対象に含められるため、スナップショットに依存するモデルを含む一括検証に向きます。

  • incremental: 変更量が多いときは --full-refresh を計画的に(ロックやコストに注意)
  • snapshot: 選択子で含めると build が実行。未選択なら既存テーブルを参照
  • テストは生成物に対して実行されるため、更新直後の健全性確認が容易
対象run/build 共通のポイント注意点
incremental モデル差分適用。--full-refresh で全再計算キーや unique_key の設定誤りは静かに重複を生み得る
snapshot選択すれば build が実行・検証スケジュールと依存関係を明示。不要に毎回全表比較しない

スナップショットとモデルの依存

sourcesnapshot:customers_scd1) 必要なら実行dim_customers2) model 実行tests3) dim_customers のテストbuild -s dim_customers: snapshot → model → test の順で実行

設定例:インクリメンタルとスナップショット

# models/fct_orders.sql
{{ config(materialized='incremental', unique_key='order_id') }}
select * from {{ ref('stg_orders') }}
{% if is_incremental() %}
  where updated_at > (select max(updated_at) from {{ this }})
{% endif %}

# snapshots/customers.sql
{% snapshot customers_scd %}
{{ config(strategy='timestamp', unique_key='customer_id', updated_at='updated_at') }}
select * from {{ source('app', 'customers') }}
{% endsnapshot %}

# 実行
# 影響範囲を含め一括構築・検証
dbt build -s +dim_customers
# 全再計算(注意して計画的に)
dbt run -s fct_orders --full-refresh

CI/CD と本番運用での判断基準

PR 検証や本番前の整合性チェックは dbt build が第一選択です。構築とテストを一発でカバーし、失敗があれば早期に検出できます。

ローカル開発やデバッグは dbt run で対象を最小化して素早く反復し、論点が固まったら build でテストまで通すのが効率的です。

  • 開発: run で速く確認 → 節目で build
  • CI: build -s state:modified+ --defer --state を基本形に
  • 本番バッチ: build で包括的に。テストの一部を除外したい場合は --exclude
シーン推奨コマンド理由
ローカル開発dbt run -s +対象最小スコープで反復速度を優先
PR/CIdbt build -s state:modified+ --defer変更影響の構築とテストを一括で担保
本番前リハーサルdbt build本番相当の包括的検証

CI パイプラインの典型

[PR] Checkoutdbt depsdbt build-s state:modified+ --defertest レポートartifactsPR → deps → build (state:modified+ --defer) → test レポート

GitHub Actions の最小ジョブ例

jobs:
  dbt-ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - run: pip install dbt-core dbt-bigquery  # 適宜アダプタ
      - run: dbt deps
      - run: dbt build -s state:modified+ --defer --state target

落とし穴と試験対策の着眼点

試験では定義の厳密さが問われます。特に「dbt build は何を対象にするか」「テストがいつ動くか」「未選択ノードの扱い」を正確に押さえましょう。

実務では、選択子の過不足や full-refresh の濫用がコスト・ロック・誤検知の原因になります。ルール化と自動化で回避します。

  • 未選択の親は自動で再実行されない。必要なら + を付けるか明示選択
  • build は tests を実行するが、未選択ノードに紐づくテストは走らない
  • full-refresh は計画的に。並列度とロックの相互作用に注意
誤解しがち正しい理解対処
build は常に全テストを回す選択スコープに紐づくテストのみ実行-s/-x で範囲を明示
子モデルを選べば親も自動実行される選択しない限り再実行はされない+ を使って依存を含める
run と build は速度が同じbuild はテスト分だけ時間が伸びる開発は run、ゲートは build

意思決定の分岐

目的は何か?速く確認したい→ dbt run合格判定したい→ dbt build範囲は?selectors で最小化目的で run / build を選び、範囲は selectors で最小化

試験向けミニチェック(自問)

- dbt run: 何が動く? models のみ
- dbt build: 何が動く? seeds/snapshots/models + tests
- テストはいつ? 対象ノードの構築後
- 親子を含める? +で選択範囲を拡張

問題で確認

Analytics Engineer

問題 1

開発者が PR を作成し、変更したモデルとその下流に対して構築と関連テストを自動で実行したい。最も簡潔で適切なコマンドはどれか?

  1. dbt run -s state:modified+
  2. dbt test -s state:modified+
  3. dbt build -s state:modified+
  4. dbt build && dbt test -s state:modified+

正解: C

dbt build は seeds/snapshots/models をDAG順に実行し、該当ノードのテストを続けて実行する。state:modified+ で変更とその下流を対象にでき、PR/CI の最短経路になる。run はテストを実行しない。

よくある質問

dbt build でテストが失敗したら、モデルの成果物はロールバックされますか?

既定ではロールバックされません。モデルの実行は成功し、後続のテストで失敗が記録されます。必要に応じてトランザクション設定やワークフロー側で失敗時のクリーンアップを設計します。

build で一部の重いテストだけ除外したい場合は?

選択子で除外します。例: dbt build -s +mart_orders -x test_type:data など。特定のタグをテストに付け、-x tag:heavy_test のように除外するのが実務的です。

run と build の速度差を最小化するには?

選択子で最小範囲にし、並列度(--threads)を適正化。テストは重いものをタグで夜間に回す、スキーマテストは常時、データテストはバッチ的に分離するなどの戦略を取ります。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
dbt

dbt Model の基礎: SQL で定義する変換の最小単位

Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...

dbt

dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点

dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...

dbt

dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点

dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...

dbt

dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト

Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....

dbt

dbt_project.yml の読み方:主要設定と命名を最短で掴む

dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...

dbtの記事一覧 (100件)
© 2026 NicheeLab All rights reserved.