ふくふくHukuhuku Inc.
EP.04dbt 10分公開: 2026-05-10

ref() と source() で依存関係を組む:dbt の核心

dbt の `ref()` `source()` は単なるテーブル参照ではなく、依存グラフを宣言する仕組み。これを正しく使うと環境切替・並列実行・lineage が自動で手に入る。具体例と落とし穴を整理。

#dbt#ref#source#DAG#lineage
シェア

の最大の発明は `ref()` 関数です。テーブル名を直接書く代わりに `ref('model_name')` と書くことで、dbt は 依存関係グラフ ( の DAG) を自動構築し、環境別の正しいテーブル名を解決し、並列実行スケジュールを最適化します。

ref() の挙動

ref() の解決例
SQL
-- model: marts/dim_customers.sqlSELECT * FROM {{ ref('stg_customers') }}
-- dev 環境では:-- → SELECT * FROM dbt_dev_yourname.stg_customers
-- prod 環境では:-- → SELECT * FROM analytics_prod.stg_customers
-- CI 環境では:-- → SELECT * FROM ci_pr_42.stg_customers

テーブル名のハードコードを避けることで、環境切替が dbt 側で勝手に行われる。これが「ローカルで開発し、PR で CI ビルド、merge で prod 反映」のフローを成立させる土台。

source() との使い分け

関数参照先使う場所
`source('schema', 'table')`dbt の外で作られた生テーブル で取込済み)staging のみ
`ref('model_name')`dbt 内で作った modelstaging/intermediate/marts 全部
原則: source() は staging だけで使う

marts や intermediate で `source()` を直接使うと、staging レイヤをバイパスする model ができる。これは 「同じソーステーブルを複数の場所で型変換する」事故の元。1 source = 1 staging model = ref() 経由でしか触らない を徹底。

依存グラフ (DAG) の確認

lineage を可視化
Bash
# ドキュメント生成 → ブラウザで lineage グラフ確認dbt docs generatedbt docs serve
# CLI で依存を見るdbt list --select +fct_orders --output json | jq '.[].depends_on'
# 特定 model に到達する全 modeldbt list --select +fct_orders --resource-type model

ref() の便利な使い方

1. version 指定

model versioning (dbt 1.5+)
SQL
-- 旧バージョンを残しつつ新バージョンに移行SELECT * FROM {{ ref('dim_customers', v=2) }}

2. パッケージ越しの参照

外部 dbt パッケージのモデル参照
SQL
SELECT * FROM {{ ref('dbt_utils', 'dim_calendar') }}

3. project 越しの参照(dbt Mesh)

別プロジェクトの公開 model 参照
SQL
-- {{ ref('別プロジェクト名', 'モデル名') }}SELECT * FROM {{ ref('marketing_analytics', 'dim_campaigns') }}

依存設計の落とし穴

1. 循環依存

`A → B → A` のような循環は dbt がエラーで弾く。意図せず出るのは大体 model 設計の問題。A から B の集計値を持ち戻すようなケースは、別 model に切り出す。

2. 深すぎる依存チェーン

5 段以上の `ref` 連鎖は、変更影響が見えづらく、ビルド時間も長くなる。intermediate を 1〜2 段に抑える設計が現実的。

3. `this` の循環参照誤用

incremental model では `this` で自テーブル参照ができるが、これを通常 model でやるとエラー。Incremental 用途以外では使わない。

ベストプラクティス

  • `source` は staging だけ、他レイヤは必ず `ref()`
  • 1 staging model = 1 source table、JOIN しない
  • intermediate は最大 1 段、それ以上は marts に直接
  • marts どうしの ref() は最小限 ── 上下関係が崩れる
  • lineage を毎回確認: 新 model 追加時は `dbt docs serve` で意図したグラフか目視

次の話

EP.05 では materialization 4 種 (view / table / incremental / ephemeral) の使い分けを扱います。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp