dbt では Jinja コンテキストに graph という読み取り専用オブジェクトがあり、プロジェクト内のノード(models、sources、seeds、snapshots、tests など)や依存関係を参照できます。これにより、タグに基づく一括設定や、DAG の検査・可視化系のマクロを実装できます。
一方で、graph は依存関係を新たに作るものではありません。DAG のエッジを作るのは ref と source です。Analytics Engineer 試験でも頻出の論点なので、正しい使い分けと安全な実装パターンを押さえましょう。
graph は dbt のパース後に得られるプロジェクト全体の DAG 表現です。Jinja から読み取り専用で参照でき、各ノードの種類(resource_type)、名前、タグ、設定値、依存先(depends_on)などにアクセスできます。モデルの SQL、マクロ、スナップショット、テストなど一般的な Jinja コンテキストで利用可能です。
重要なのは、graph は依存関係を作成しない点です。DAG のエッジを作るのは ref、source(および test の内部など)であり、graph はあくまで“見る専用”。この前提を外さなければ、プロジェクト全体の健全性チェックやメタデータ駆動のガードレール実装に強力です。
| コンテキスト/関数 | 主用途 | 依存関係を作るか | 利用できる場所 |
|---|---|---|---|
| graph | DAG 情報の参照・検査 | 作らない | モデル/マクロ/テスト等 |
| ref | モデル参照・依存作成 | 作る | モデル/マクロ |
| source | ソース参照・依存作成 | 作る | モデル/マクロ |
| this | 現在ノードの識別子 | 作らない | モデル/テスト等 |
| target | 接続先プロファイル情報 | 作らない | 全般 |
DAG と graph 参照の関係(概念図)
例: graph を使って下流モデルを列挙するマクロ(run-operation 用)
{% macro show_children(model_name) %}
{# 対象モデルのノードを取得 #}
{% set target = (graph.nodes.values()
| selectattr('resource_type', 'equalto', 'model')
| selectattr('name', 'equalto', model_name)
| list | first) %}
{% if not target %}
{{ exceptions.raise_compiler_error('Model not found: ' ~ model_name) }}
{% endif %}
{% set children = [] %}
{% for n in graph.nodes.values() if n.resource_type == 'model' %}
{% if target.unique_id in n.depends_on.nodes %}
{% do children.append(n.name) %}
{% endif %}
{% endfor %}
{{ log('children(' ~ model_name ~ '): ' ~ (children | join(', ')), info=True) }}
{% endmacro %}
{# 使い方:
dbt run-operation show_children --args '{"model_name": "stg_orders"}'
#}graph.nodes は辞書(unique_id → ノード)で、values() からノードの配列的アクセスができます。実務では resource_type でまず絞り込み(model、source、seed、snapshot、test など)、さらに name、package_name、tags、config(materialized、schema、post-hook 等)で必要な対象に限定します。
依存関係は node.depends_on.nodes に unique_id の配列として格納されます。上流(parents)は自ノードの depends_on、下流(children)は全ノードを走査して自分の unique_id を depends_on.nodes に含むノードを拾う、という要領です。
Jinja の selectattr、map、rejectattr、unique、list などのフィルタと組み合わせると、宣言的にノード集合を扱えます。例えばタグでの制御、特定フォルダ配下モデルの集計、マテリアライゼーション別の統計などが簡潔に書けます。
大規模プロジェクトでは、まず対象集合を最小化してから集計・検査を行うのがコツです。無条件に graph.nodes.values() を全走査するマクロは、パース時間を押し上げる原因になり得ます。
graph を用いたルールチェックは現場で効きます。例として、mart タグのモデルに必須テストが無い場合にビルドを失敗させる、staging 層から mart 層へ直結していないかを検査する、などが挙げられます。
また、運用ダッシュボード向けに、モデル数・テスト数・タグ別の分布などを run-operation で吐き出し、CI のアーティファクトとして保存するパターンも安定的に運用できます。
graph は dbt が解釈したプロジェクトの静的情報であり、データベースの実体や行数などの実行時情報は含みません。スキーマ内の実在オブジェクト照会は adapter 経由の情報取得(get_relation 等)を使い、graph と混同しないようにします。
依存関係は ref・source でのみ作成されます。graph を見て判断しても DAG は変わらないため、実行順序や並列性に影響を与えたい場合は ref/source の利用、もしくは selection 記法(+、@、state:modified 等)で制御します。
試験では、依存関係を作る手段とそうでない手段の区別、graph の位置づけ、Jinja コンテキストの代表的な変数(this、target、var、env_var など)の使い分けがよく問われます。graph は DAG の introspection 用であり、実行順序を左右しない、という一言で説明できるようにしておきましょう。
加えて、depends_on による親子関係の把握や、resource_type/tag を用いた集合操作の基礎を押さえておくと、シナリオ問題にも対応しやすくなります。
Analytics Engineer
問題 1
dbt の Jinja で DAG 情報を参照し、タグ 'mart' のモデルに必須テストが設定されているかをチェックしたい。正しいアプローチはどれか。
正解: A
graph は読み取り専用で、DAG の introspection に使います。依存関係の作成は ref/source の責務です。データベースのオブジェクト列挙や環境変数からの DAG 構築は、dbt の公式な依存関係管理の仕組みではありません。
graph はモデルの SQL 本体からも参照できますか?
はい。一般的な Jinja コンテキストで参照できます。とはいえ、重い全走査を各モデルで行うとパース時間が増えるため、run-operation のマクロとして切り出すなど運用上の工夫がおすすめです。
ノードの属性はどれまで頼ってよいですか?
name、resource_type、package_name、tags、config、depends_on などの基本属性は実用上安定しています。ユニーク識別には unique_id を使うのが無難です。将来変更の可能性がある詳細な内部構造に依存しすぎない設計にしましょう。
下流ノードを簡単に取得するビルトインはありますか?
Jinja から直接のショートカットはないため、depends_on を用いて走査します。運用では CLI の selection 記法(例: dbt ls --select +model_name)を併用すると、解析コストを抑えつつ同等の結果が得られます。
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)、設定優先度...