dbtはSQL変換、Jinja、アダプター経由の接続、選択ルール、テストといった複数レイヤーが絡みます。エラーは層ごとに性質が異なり、正しく切り分けないと時間を失いがちです。
この記事では、現場で多い失敗パターンを層ごとに整理し、再現性のある確認手順と安定解を提示します。Analytics Engineer試験で問われるコマンド差分やインクリメンタルの要件にも触れます。
最初に確認すべきはprofiles.ymlとアダプターの整合です。dbt_project.ymlのprofile名、profiles.ymlのターゲット、認証方式、そしてアダプタープラグインの導入状況をdbt debugで検証します。
ネットワークや権限に起因するエラーはdb接続レイヤーの典型です。認証エラー、スキーマ未作成、ロール不足など、エラーメッセージの語彙で大枠を特定し、最小構成での接続テストへ切り戻します。
| コマンド/ファイル | 目的 |
|---|---|
| dbt debug | アダプター、認証、プロファイルの健全性チェック |
| dbt --version | アダプターとdbt-coreの互換性・インストール確認 |
| profiles.yml | 接続先、資格情報、ターゲット(target)の定義 |
| dbt_project.yml | profileキーの一致、モデルのデフォルト設定確認 |
接続トラブルの初動フロー
最低限のprofiles.yml例(Snowflakeの例。環境変数併用)
snowflake_profile:
target: dev
outputs:
dev:
type: snowflake
account: "{{ env_var('SNOWFLAKE_ACCOUNT') }}"
user: "{{ env_var('SNOWFLAKE_USER') }}"
password: "{{ env_var('SNOWFLAKE_PASSWORD') }}"
role: ANALYST
database: ANALYTICS
warehouse: TRANSFORMING
schema: DEV
threads: 8
client_session_keep_alive: truedbtのノード選択はref()依存やタグ、パスが絡みます。No nodes selectedはセレクタが空集合になったサインです。dbt lsで対象を先に可視化してから本番コマンドを流すと事故が減ります。
runとbuildの違いは試験でも頻出です。buildはmodels, tests, snapshots, seeds, exposuresを依存順に包括実行します。CIではbuildが既定路線ですが、意図せぬseed上書きやtest失敗による停止を理解しておく必要があります。
| コマンド | 対象ノード | 代表的なオプション | 失敗の主因 |
|---|---|---|---|
| dbt run | modelsのみ | -s/--select, -m(同義), --defer | No nodes selected, 依存欠如, コンパイル失敗 |
| dbt build | models + tests + snapshots + seeds | --fail-fast, --select, --exclude | テスト失敗で停止、seed上書き、順序依存のエラー |
| dbt test | generic/singular tests | --select, --store-failures | NULL/重複検出などの品質エラー |
| dbt seed | CSV→テーブル | --full-refresh, --show | カラム型不一致、引用符設定、上書き注意 |
| dbt source freshness | sources | --select, --output json | 最大遅延超過、メタデータ権限不足 |
対象可視化と安全な選択の例
# まずは対象を確認
/dbt ls -s tag:daily +
# 変更分のみ(state:modified)
/dbt ls -s state:modified --state ./target
# 本実行(依存先も含める)
/dbt build -s tag:daily+ --fail-fast
# パッケージ衝突回避のエイリアス(dbt_project.ymlの例)
models:
my_pkg:
+alias: pkg__{{ model.name }}インクリメンタルは一見便利ですが、unique_keyやis_incremental()の条件式が曖昧だと取り込み漏れや重複を生みます。merge戦略ではunique_keyがほぼ必須です。フルリフレッシュが混在するCI/本番でも壊れない条件式が鍵です。
スキーマ変更はon_schema_changeの設定と、アダプターが対応しているかで挙動が変わります。未対応の組み合わせではDatabase Errorが出るため、同期ポリシーを明示し、必要に応じて--full-refreshで初期化します。
| 症状 | 典型原因/対処 |
|---|---|
| Database Error: MERGE requires a unique match | config(unique_key=...)を設定。ユニーク性を保証するキーを再設計 |
| 取り込み漏れが断続的に発生 | is_incremental()のWHEREがゆるい。境界を>=最終タイムスタンプ+1単位に見直し |
| 列追加後に失敗 | on_schema_changeの同期方針をsync_all_columns等に設定。未対応なら--full-refresh |
| 実行は成功するが重複増加 | unique_keyが複合必要。coalesce/正規化で一意性を担保 |
堅牢なインクリメンタルモデル例
{{ config(
materialized='incremental',
unique_key='id',
on_schema_change='sync_all_columns'
) }}
with src as (
select * from {{ ref('stg_events') }}
)
select
id,
event_ts,
payload
from src
{% if is_incremental() %}
where event_ts > (
select coalesce(max(event_ts), '1970-01-01') from {{ this }}
)
{% endif %}作成先スキーマが存在しない、あるいは作成権限がない場合、モデル作成前に失敗します。運用ではデプロイ用ロールにCREATE/USAGE権限を明確に付与し、初回のみon-run-startでCREATE SCHEMAを自動化する方法もあります。
識別子の大文字小文字や予約語はアダプターごとに扱いが異なります。dbtのquoting設定でidentifier/schemaの引用有無を統一し、aliasで明示的に名前を固定するのが安全です。
| 権限 | 説明 |
|---|---|
| USAGE (DB/SCHEMA) | オブジェクト参照に必要。これが無いと存在確認も不可 |
| CREATE (SCHEMA/TABLE/VIEW) | 生成時に必須。マテリアライズで失敗しやすい |
| SELECT/INSERT/UPDATE/DELETE | モデルの読み書きで必要。incrementalは更新系も利用 |
クオートとスキーマの安定化(profiles.yml / モデル設定)
# profiles.ymlの例(識別子を常に引用)
quoting:
database: false
schema: true
identifier: true
# モデル側でのエイリアス固定(models/*.sqlの先頭)
{{ config(alias='fact_events', schema='prod') }}Compilation ErrorはJinja解釈段階の失敗です。未定義の変数やマクロ、型不整合が原因のことが多く、dbt parseで早期に発見できます。varsはデフォルトを与えて堅牢化します。
パッケージ由来のマクロ未検出はdbt deps未実行やバージョン不整合が典型です。packages.ymlのピン留め、名称衝突時のdispatchルールを見直します。
| エラー文 | 修正の方向性 |
|---|---|
| 'var_x' is undefined | varsに定義 or var('var_x', default)に置換 |
| Macro 'pkg.my_macro' not found | packages.ymlにpkgを追加しdbt deps。バージョンを固定 |
| Could not render {{ ref('x') }} | 参照先のリソース名/パス/パッケージ前置きを修正 |
varsのデフォルト/パッケージ管理の例
# モデル内での安全なvars参照
select * from {{ ref('stg_users') }} where country = '{{ var('country', 'JP') }}'
# packages.yml(一例)
packages:
- package: dbt-labs/dbt_utils
version: ">=1.0.0,<2.0.0"
# 検証
/dbt deps
/dbt parseテスト失敗は品質の仕様通りに検知しているかをまず確認します。NULLや重複が許容される期間・例外の取り扱いをモデル側で吸収するか、test側で条件を与えるかを決めます。
source freshnessは最大遅延を超えると失敗します。スケジューラと取り込みサイクルの整合を取り、運用ではJSON出力を監視に流すと効果的です。
| 失敗シナリオ | 切り分けの観点 |
|---|---|
| unique/accepted_valuesテスト失敗 | モデル計算とビジネス仕様の差分。WHERE条件付テストに見直し |
| freshness遅延超過 | 取り込み基盤の遅延 or ラグ閾値の設定ミス |
| seed差分でCI失敗 | CSV更新の認識漏れ。型・NULL表現・引用の差異を統一 |
テスト/鮮度/CIの実用スニペット
# tests/schema.yml(一例)
models:
- name: dim_users
tests:
- unique:
column_name: user_id
- not_null:
column_name: user_id
sources:
- name: app
tables:
- name: events
freshness:
warn_after: {count: 12, period: hour}
error_after: {count: 24, period: hour}
loaded_at_field: event_ts
# CIではbuildで包括実行
git diff --name-only | xargs -I{} echo {}
/dbt build --select state:modified+ --state ./target --fail-fast --warn-error
/dbt source freshness --select source:app.events --output jsonAnalytics Engineer
問題 1
incrementalモデルがmerge戦略で実行されており、dbt run時に重複行が増えている。安定した再実行を保証する最適な修正はどれか?
正解: A
merge戦略では一意に突き合わせるキーが必要で、unique_key未設定や曖昧な時間境界は重複の原因です。unique_keyを明示し、is_incremental()の条件を再実行でも決定的になるよう修正するのが正解。テスト有無や並列数は根本解決になりません。
dbt runが失敗したSQLを特定する最短手順は?
まずdbt build/runを--fail-fastで実行し、target/run/<package>/<model>.sqlの生成物を開いてDWH上で単体実行します。併せてdbt debugで接続問題を切り分けます。
No nodes selectedの再発を防ぐには?
本実行前にdbt ls -s <selector>で対象を確認する運用にします。タグ/パス/stateの複合指定では+(依存)やexcludeを明示し、セレクタをリポジトリ内で共通化します。
スキーマ作成権限が無い環境での初回デプロイは?
事前に管理者がスキーマを作成し、実行ロールにUSAGE/CREATE(テーブル/ビュー)/DML権限を付与します。もしくは初回のみ管理者ロールでon-run-startにCREATE SCHEMAを仕込み、以後は通常ロールで運用します。
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)、設定優先度...