dbt

dbt on_schema_change オプション徹底攻略:スキーマ変化への追従と安全運用

2026-04-19
NicheeLab編集部

モデリングの寿命はスキーマ変化への耐性で決まります。dbt には、増分モデルの列追加・削除が発生した際の動きを制御する on_schema_change という重要な設定があります。

本稿では、各オプションの意味と選び方、主要データウェアハウスでの注意点、試験で狙われやすい論点を、現場の観点で解説します。

on_schema_change の基本と適用範囲

on_schema_change は、dbt の増分モデルでターゲットテーブルとモデルの列集合が食い違ったときの挙動を決めるモデル設定です。検知対象は「列の追加・削除」です。型変更は基本的に対象外で、DDL が必要な場合は別途対応します。

適用範囲は増分マテリアライズのみです。table や view、ephemeral には効きません。検知は、ターゲットリレーションの実際の列と、コンパイル後モデルの列リストを突き合わせることで行われます。

  • 主に増分戦略 merge と組み合わせて使う
  • デフォルトは ignore(無視して続行)
  • full_refresh 実行時は on_schema_change に関係なく新規作成で整合が取れる

最小設定例:モデル内で on_schema_change を指定

{{
  config(
    materialized='incremental',
    incremental_strategy='merge',
    unique_key='id',
    on_schema_change='append_new_columns'
  )
}}

select
  id,
  event_time,
  value,
  -- 将来ここに新規列が増える想定
  from {{ ref('stg_events') }}

選択肢の意味と違い:どれをいつ選ぶか

on_schema_change の主な選択肢は ignore, fail, append_new_columns, sync_all_columns の4つです。違いは、新規列の取り込みと既存列の削除を自動で行うか、検知時にビルドを止めるか、に集約されます。

安全側に倒すなら fail、継続性を重視して新規列のみ受け入れるなら append_new_columns、モデル定義を常に真実としたいなら sync_all_columns が実務での定番です。

  • デフォルト挙動は ignore。試験では明示指定なしの落とし穴として問われやすい
  • 列削除の自動反映が必要なら sync_all_columns。ただし倉庫の制約に注意
  • 変更審査フローがある現場では fail を使い計画的に DDL を適用するパターンが多い
オプション新規列の扱い削除列の扱い型変更の扱い
ignore無視(既存列のみでDML)無視(ターゲットに残存)対象外(多くは未対応)
fail検知時にエラーで停止検知時にエラーで停止対象外(型差異は別途)
append_new_columnsALTER TABLE で追加無視(ドロップしない)対象外(別対応)
sync_all_columns追加する削除する(倉庫依存)対象外(別対応)

プロジェクト既定として指定(dbt_project.yml)

models:
  marts:
    +materialized: incremental
    +incremental_strategy: merge
    +on_schema_change: sync_all_columns

主要データウェアハウスでの挙動差と注意

Snowflake は ALTER TABLE の ADD/DROP COLUMN が安定しており、append_new_columns も sync_all_columns も実務で使いやすい構成です。列削除は依存オブジェクトがないことが前提です。

BigQuery は ADD/DROP COLUMN をサポートします。増分戦略が merge の場合は on_schema_change が働きますが、insert_overwrite を使う場合はテーブル再作成を伴わないため期待通りにならないことがあります。必要に応じ full_refresh を併用します。

Databricks(Delta Lake)は列追加に強く、列削除はランタイムやテーブル特性に依存します。sync_all_columns での削除は事前検証を推奨します。いずれも merge 戦略と相性が良いです。

  • Snowflake: 4オプションを実務適用しやすい。削除は権限と依存性の確認が鍵
  • BigQuery: merge では機能。insert_overwrite では期待と違う場合があるため full_refresh を検討
  • Databricks: 追加は安定。削除は環境依存なので段階的適用や検証計画が必要

ターゲット別に挙動を切り替えるヒント(環境変数を併用)

models:
  +on_schema_change: '{{ env_var("DBT_ON_SCHEMA_CHANGE", "ignore") }}'

# 実行時に上書き例
# DBT_ON_SCHEMA_CHANGE=sync_all_columns dbt run -s dim_customer

増分戦略との相性:merge / delete+insert / insert_overwrite

on_schema_change の効果は、戦略がテーブル定義を維持したまま DML を流す場合に現れます。典型は merge 戦略です。ignore のときは、ターゲットに存在しない列を除外して DML を生成するため、ビルドは成功しますが新規列は取り込まれません。

insert_overwrite(特に BigQuery)では、分割領域の置換で完結するため、on_schema_change の列追加・削除ロジックが期待通りに適用されないケースがあります。スキーマ変更を確実に反映したい場合は full_refresh と併用するのが安全です。

  • merge: on_schema_change の主戦場。unique_key は必須
  • delete+insert: 列追加は適用されるが倉庫依存の差異に注意
  • insert_overwrite: スキーマ差分の自動調整は限定的。full_refresh を計画に入れる

増分ビルド時のスキーマ差分ハンドリング フロー

dbt run start既存テーブル取得 → 列差分を算出差分なしMERGE/INSERT 実行準備差分ありon_schema_change の分岐ignore何もしないfailエラーで停止append_new_columns追加のみ実施sync_all_columns追加/削除を実施列差分を算出し on_schema_change に従って ALTER/スキップ後に DML を実行

merge 戦略での典型モデル

{{
  config(
    materialized='incremental',
    incremental_strategy='merge',
    unique_key='order_id',
    on_schema_change='sync_all_columns'
  )
}}
select
  order_id,
  customer_id,
  total_amount,
  updated_at
from {{ ref('stg_orders') }}

運用パターン:安全な適用、ロールバック、監査

新規列の段階的導入は append_new_columns を既定にし、数サイクル後に sync_all_columns へ切り替えると影響範囲を抑えられます。列削除は影響調査と依存オブジェクトの洗い出しを済ませてから同期を有効化します。

失敗時の復旧は、まず fail で停止させ、テーブルバックアップを確認、必要なら --full-refresh で再作成し、以降の増分に戻します。変更は dbt のログに残るため、監査には run_results.json と invocation_id を活用します。

  • 小さく始めて段階的に厳格化(ignore → append → sync)
  • 削除は計画停止時間帯に実施し、検証環境で事前演習
  • run_results.json に DDL の痕跡が残るようログ保存を仕組み化

代表的な運用コマンド

# ふつうの増分ビルド
 dbt run -s fact_sales

# 強制的に作り直してスキーマを確実に適用
 dbt run --full-refresh -s fact_sales

# 失敗時のトラブルシュート用にデバッグ
 dbt debug && dbt ls -s fact_sales && dbt compile -s fact_sales

試験対策:よく出る論点と落とし穴

Analytics Engineer 試験では、on_schema_change の既定値、各オプションの違い、いつ full_refresh が必要か、戦略ごとの適用可否が狙われます。型変更が対象外である点や、view には効かない点もチェックポイントです。

モデル契約(contract enforced: true)を使うと、列の過不足でビルドが失敗します。on_schema_change は DDL の自動適用、contract はスキーマ逸脱の禁止という役割分担で、組み合わせると強固なガバナンスになります。

  • デフォルトは ignore。明示しなければ新規列は取り込まれない
  • 型変更は対象外。ALTER TYPE 相当は別途計画
  • contract を併用すると列の追加も未承認なら失敗させられる

モデル契約の例(列逸脱で失敗)

models:
  - name: dim_customer
    config:
      contract:
        enforced: true
      materialized: incremental
      incremental_strategy: merge
      on_schema_change: fail
    columns:
      - name: customer_id
        data_type: string
      - name: customer_name
        data_type: string

問題で確認

Analytics Engineer

問題 1

増分モデル(strategy=merge)で upstream に新規列が追加された。運用を止めずに新規列も取り込みたいが、既存列の削除はまだ行いたくない。適切な on_schema_change の設定はどれか。

  1. append_new_columns
  2. sync_all_columns
  3. ignore
  4. fail

正解: A

append_new_columns は新規列のみ ALTER TABLE で追加し、削除は行いません。ビルドは続行し、過去行の新規列は NULL で埋まるのが一般的です。sync_all_columns は削除も行う可能性があるため要件と不一致、ignore は新規列を取り込みません。fail は検知で停止します。

よくある質問

on_schema_change は型変更(STRING→INT など)も自動で適用するか?

いいえ。対象は列の追加・削除です。型変更は倉庫固有の制約が大きく、dbt は自動変換しません。別途 ALTER COLUMN や full_refresh を計画します。

view や table マテリアライズにも on_schema_change は効くか?

いいえ。on_schema_change は増分マテリアライズ向けの設定です。view は再作成で常に最新スキーマを反映、table は再作成や full_refresh で対応します。

デフォルトの ignore で新規列を参照する SQL に変えたらビルドは失敗する?

通常は失敗しません。dbt はターゲットに存在しない列を除外して DML を生成します。ただし新規列は取り込まれません。取り込みたい場合は append_new_columns か sync_all_columns を使います。

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

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.