dbt

dbt Sources と freshness: 外部テーブルの宣言と鮮度チェック

2026-04-19
NicheeLab編集部

dbt の Source は、dbt が作成しない上流の既存テーブルを宣言して依存関係グラフに取り込み、テストや鮮度チェックを可能にします。

本稿では、Snowflake や Databricks など代表的な環境を念頭に、外部テーブルの宣言と freshness チェックの設計・運用・試験対策を実務目線で解説します。

Sources の基本と設計意図

dbt の Source は、Fivetran などの EL ツールがロードした上流のテーブルやビューを、dbt プロジェクト内で明示的に宣言する仕組みです。これにより、参照の安定化、ドキュメント化、テスト、鮮度チェックが可能になります。

宣言は通常 models ディレクトリ配下の yml ファイル(version: 2)に記述します。name、database、schema、identifier を用いて物理名を正確に指すのが基本です。大文字小文字や引用符の扱いはアダプタごとに異なるため、必要に応じて quoting を設定します。

  • dbt の Source は「外部=dbt 管理外」のオブジェクトを論理名で安定参照するための宣言
  • identifier で物理テーブル名を正確に指し、name は論理名としてモデルから呼び出す
  • 最小限のテーブルのみ宣言し、使われなくなったものは整理する
  • Snowflake など大文字が多い環境では 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

外部テーブルの宣言パターン(Snowflake / Databricks)

アダプタにより database と schema の解釈や大文字小文字の扱いが異なります。Snowflake はデータベース・スキーマ・オブジェクト名の三部構成で、ケース感度は引用符の有無に依存します。Databricks(Unity Catalog 有効)ではカタログ・スキーマ・テーブルの三部構成で、dbt 側の database フィールドがカタログに対応する実装が一般的です(詳細はご利用の dbt-adapter のドキュメントを確認してください)。

実務では、物理名が確定している外部テーブルに対し、identifier に物理名、name に論理名をつけ、必要に応じて quoting を明示します。これにより環境差分やリネーム時の影響を抑えられます。

  • Snowflake では引用符の扱いに注意。物理名が大文字固定なら quoting を有効化すると安全
  • Databricks Unity Catalog では database をカタログ、schema をスキーマとして指定する設計が一般的
  • 上流のスキーマ移動やリネームに備え、identifier と name を分離しておく

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 の基本設定と評価の仕組み

freshness は loaded_at_field の最大値と実行時刻の差分(age)を評価し、warn_after と error_after の閾値に基づいて pass/warn/error を判定します。loaded_at_field は行単位の取り込み完了時刻を表すタイムスタンプ列であることが前提です。

filter は loaded_at_field の評価対象行を絞り込む追加条件で、アダプタの SQL 方言に準じた断片を指定します。例えばテストデータや論理削除行を除外するのに有効です。

  • ステータス判定: pass < warn_after < error_after
  • 評価時刻は実行先データベースの現在時刻に依存する
  • loaded_at_field は NULL を含まないことが望ましく、必要なら filter で除外
  • freshness は source テーブル単位。source レベルの設定はデフォルトとして継承・上書き可能

Source と freshness の評価フロー(概念図)

上流取り込み(EL)外部テーブル(物理)dbt Source 宣言loaded_at_field / freshnessdbt source freshnessmax(loaded_at_field) vs 現在時刻pass / warn / error を出力上流取り込み → 外部テーブル → dbt Source → freshness 評価 → pass/warn/error

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 などが出力されます。外部連携やダッシュボードでの可視化に利用できます。

  • error が出たらパイプラインを停止または下流の build を抑止する運用が安全
  • sources.json を保管し、時系列で age をトラッキングすると傾向が見える
  • 長期のバルクロード期間は一時的に閾値を緩めるなど運用上の例外を管理

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"
    }
  }
}

運用パターン: CI/スケジュールへの組み込み

freshness はスケジュール実行や CI でのゲートに組み込むと効果的です。下流の dbt build を走らせる前に freshness をチェックし、error の場合は以降のステップをスキップする構成が安全です。

環境差分(本番・検証)で閾値が異なる場合、YAML 内で Jinja 変数を使って warn_after の count を外出しする運用が実務でよく使われます。

  • ジョブの先頭で dbt source freshness を実行し、非ゼロ終了なら以降を停止
  • Jinja 変数や環境変数で閾値をパラメータ化して環境差分を吸収
  • 一時的な遅延はチケット化し、閾値変更をレビュー付きで管理

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 は既存テーブル、ref は dbt モデル。freshness は source のみ対象
  • loaded_at_field は最大値を使う。warn_after と error_after の単位 period を選べる
  • filter は WHERE 句断片として評価行を制限。NULL を除外するのに有効
  • selectors: source:raw.orders のように source:<source_name>.<table_name> が使える

モデルから 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) は除外したい。正しい設定はどれか。

  1. sources.yml の orders テーブルに loaded_at_field と freshness(warn_after/error_after) と filter: "_is_test = false" を設定する
  2. models/stg_orders.sql の SELECT に WHERE 句で _is_test = false を入れ、dbt test で鮮度も検証する
  3. dbt run の前に dbt build を実行し、ref で参照しているモデルに freshness を設定する
  4. sources.yml に freshness を設定せず、代わりに tests: - freshness を追加する

正解: 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 もテーブルごとに指定可能です。

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

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の記事一覧 (101件)
© 2026 NicheeLab All rights reserved.