dbt の Source は、dbt が作成しない上流の既存テーブルを宣言して依存関係グラフに取り込み、テストや鮮度チェックを可能にします。
本稿では、Snowflake や Databricks など代表的な環境を念頭に、外部テーブルの宣言と freshness チェックの設計・運用・試験対策を実務目線で解説します。
dbt の Source は、Fivetran などの EL ツールがロードした上流のテーブルやビューを、dbt プロジェクト内で明示的に宣言する仕組みです。これにより、参照の安定化、ドキュメント化、テスト、鮮度チェックが可能になります。
宣言は通常 models ディレクトリ配下の yml ファイル(version: 2)に記述します。name、database、schema、identifier を用いて物理名を正確に指すのが基本です。大文字小文字や引用符の扱いはアダプタごとに異なるため、必要に応じて quoting を設定します。
| 項目 | source ({{ source() }}) | ref ({{ ref() }}) | seed |
|---|---|---|---|
| 作成対象 | 既存テーブルを参照のみ | dbt が作成するモデルを参照 | CSV から dbt が作成 |
| 参照方法 | {{ source('src','tbl') }} | {{ ref('model_name') }} | {{ ref('seed_name') }} |
| 依存グラフ | 上流ノードの起点として可視化 | 下流モデル間の依存を可視化 | シードを起点に可視化 |
| 品質管理 | テスト可・freshness 可 | テスト可・freshness 対象外 | テスト可・freshness 対象外 |
| 用途 | 外部システムの取り込み結果 | 変換レイヤの再利用 | 小規模マスタやテストデータ |
最小構成の sources.yml 例
version: 2
sources:
- name: raw
database: ANALYTICS
schema: RAW
loader: fivetran
tables:
- name: orders
identifier: ORDERS
- name: customers
identifier: CUSTOMERS
アダプタにより database と schema の解釈や大文字小文字の扱いが異なります。Snowflake はデータベース・スキーマ・オブジェクト名の三部構成で、ケース感度は引用符の有無に依存します。Databricks(Unity Catalog 有効)ではカタログ・スキーマ・テーブルの三部構成で、dbt 側の database フィールドがカタログに対応する実装が一般的です(詳細はご利用の dbt-adapter のドキュメントを確認してください)。
実務では、物理名が確定している外部テーブルに対し、identifier に物理名、name に論理名をつけ、必要に応じて quoting を明示します。これにより環境差分やリネーム時の影響を抑えられます。
Snowflake と Databricks の宣言例(同一ファイル内に併記する場合)
# version: 2 はファイル先頭に一度だけ宣言
version: 2
sources:
# Snowflake 例
- name: raw_snowflake
database: PROD
schema: EXT
quoting:
database: true
schema: true
identifier: true
tables:
- name: clickstream
identifier: EXT_CLICKSTREAM
description: "外部取り込みのクリックストリーム"
# Databricks (Unity Catalog) 例
- name: raw_uc
database: main_catalog # 多くのアダプタで catalog に相当
schema: bronze
tables:
- name: events
identifier: events # 物理名と同一のケース
freshness は loaded_at_field の最大値と実行時刻の差分(age)を評価し、warn_after と error_after の閾値に基づいて pass/warn/error を判定します。loaded_at_field は行単位の取り込み完了時刻を表すタイムスタンプ列であることが前提です。
filter は loaded_at_field の評価対象行を絞り込む追加条件で、アダプタの SQL 方言に準じた断片を指定します。例えばテストデータや論理削除行を除外するのに有効です。
Source と freshness の評価フロー(概念図)
freshness 設定と実行例
version: 2
sources:
- name: raw
schema: RAW
freshness: # デフォルト(テーブルで上書き可)
warn_after: {count: 24, period: hour}
error_after: {count: 48, period: hour}
tables:
- name: orders
identifier: ORDERS
loaded_at_field: _loaded_at
freshness:
warn_after: {count: 6, period: hour} # このテーブルだけ厳しめ
filter: "_is_test = false" # 評価対象の行を絞る
# 実行コマンドの例(シェル)
# 全 Source の鮮度
# dbt source freshness
# 特定 Source のみ
# dbt source freshness --select source:raw.orders
dbt source freshness 実行後、CLI にステータスサマリが表示されます。少なくとも1件でも error があれば非ゼロで終了します。warn は終了コードに影響しませんが、監視では通知対象にするのが一般的です。
アーティファクトとして target/sources.json が生成され、各 Source テーブルの max_loaded_at、snapshotted_at(計測時刻)、age、status などが出力されます。外部連携やダッシュボードでの可視化に利用できます。
sources.json のイメージ(抜粋)
{
"metadata": {"generated_at": "2026-04-19T12:34:56Z"},
"sources": {
"raw.orders": {
"max_loaded_at": "2026-04-19T11:00:00Z",
"snapshotted_at": "2026-04-19T12:34:56Z",
"age": 1.58,
"status": "pass"
},
"raw.clickstream": {
"max_loaded_at": "2026-04-17T03:10:00Z",
"snapshotted_at": "2026-04-19T12:34:56Z",
"age": 57.41,
"status": "error"
}
}
}
freshness はスケジュール実行や CI でのゲートに組み込むと効果的です。下流の dbt build を走らせる前に freshness をチェックし、error の場合は以降のステップをスキップする構成が安全です。
環境差分(本番・検証)で閾値が異なる場合、YAML 内で Jinja 変数を使って warn_after の count を外出しする運用が実務でよく使われます。
CI ジョブ例(Bash)と変数化の一例
# Bash: freshness が error なら以降の build を止める
set -e
# 依存取得とスキーマ検証(任意)
dbt deps
# 鮮度チェック(特定 Source のみ等も可)
dbt source freshness --select source:raw.*
# 問題なければ下流を実行
dbt build --select +marts:tag:daily
# YAML での変数化イメージ(Jinja)
# warn_after: {count: {{ var('freshness_hours', 24) }}, period: hour}
dbt Analytics Engineer 試験では、source と ref の違い、loaded_at_field と freshness の関係、filter の役割、選択セレクタの使い方が頻出です。特に freshness はモデルテストとは別物であり、source テーブルに対してのみ適用される点を押さえておきましょう。
また、アダプタ差異(Snowflake と Databricks)による database/schema の解釈や quoting に関する設問も出やすいため、物理名の解決ロジックを言語化できるように準備しておくと安心です。
モデルから Source を参照する例
-- models/stg_orders.sql(例)
select
o.id as order_id,
o.customer_id,
o.status,
o._loaded_at
from {{ source('raw', 'orders') }} as o
where o._is_test = false
Analytics Engineer
問題 1
dbt プロジェクトで上流の orders テーブルの鮮度を監視したい。loaded_at_field は _loaded_at、24時間で warn、48時間で error とし、テストデータ行 (_is_test = true) は除外したい。正しい設定はどれか。
正解: A
freshness は Source テーブルにのみ設定でき、loaded_at_field と warn_after/error_after、必要に応じて filter を指定します。モデルのテストや ref では鮮度は評価されません。
loaded_at_field はどんな型・値が必要ですか?
タイムスタンプ(日時)型で、各行の取り込み完了時刻を表す値が必要です。NULL が混在すると age の評価が不安定になるため、可能なら NOT NULL 制約、難しければ filter で除外するのが実務的です。
filter にはどのような書式を使いますか?
実行先データベースの SQL 方言に準じた WHERE 句の断片(WHERE は含めない)を指定します。例えば Snowflake では "_is_test = false"、Databricks/Spark でも同様のブール式が使えます。識別子の大文字小文字やクオートはアダプタに合わせて調整してください。
Source レベルで設定した freshness をテーブルごとに変えることはできますか?
できます。source ブロックにデフォルトの freshness を記載し、特定テーブルの下で freshness を上書きします。loaded_at_field もテーブルごとに指定可能です。
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)、設定優先度...