本番のダッシュボードを止めずにモデルを更新したい—その現実解が、スキーマを切り替えるBlue/Greenデプロイです。dbtはターゲットごとにスキーマを分けられるため、このパターンと非常に相性が良いです。
この記事では、ポータブルに使える「Routerスキーマ+Blue/Greenスキーマ」方式を軸に、実装例、運用の勘所、試験で問われやすいポイントをまとめます。内容はdbtの安定機能(targets、selectors、defer、state)と主要DWHの一般的な挙動に基づいています。
dbtはプロファイルのtarget単位でスキーマを切り替えられるため、Blue(現行)とGreen(切替候補)に同じモデル群を並走させるのが容易です。新しいビルドはGreenで実行し、検証後に参照を切り替えれば、読み手(BI/アプリ)へ与える影響を最小化できます。
また、dbtのstate選択子とdefer機能を併用することで、変更箇所だけをGreenに再構築しつつ、未変更部分はBlueを参照して依存解決できます。これにより、切替のスピードと安全性を両立できます。
実務で扱いやすいのは、Blue/Greenの実体スキーマと、利用者が参照する安定スキーマ(ここではRouterスキーマ)を分ける方式です。Routerスキーマにはビューを作成し、背後の参照先をBlueまたはGreenへ切り替えます。ビューのCREATE OR REPLACEは多くのDWHでメタデータ置換として扱われ、単一オブジェクトの置換は短時間かつ原子的に行われます。
留意点として、複数ビューを一括で絶対に同一瞬間に切り替えることは、DWHの機能に依存します。厳密な同時性が不要な可用性重視の分析系では、ビューを逐次置換しつつ、スキーマ互換性を維持する運用が現実的です。
Blue/GreenとRouterスキーマの構成
以下は、差分ビルドと検証を経てRouterをGreenへ切り替える標準フローです。dbtのdeferとstateを使うことで、未変更モデルを既存(Blue)から解決し、変更箇所のみGreenに構築します。
本番切替は、RouterスキーマのビューをGreenを参照する形に再作成して完了です。問題があれば、同じ手順でBlueを参照するように戻します。
2つのtargetを用意し、Blue/Greenのスキーマを固定名で割り当てます。切替はrun-operationでRouterスキーマのビューを一括で作り直します。selectorsはstate:modified+を使い、deferで未変更部分を現行に解決します。
以下は最小構成の例です。実環境では権限付与(GRANT USAGE/SELECT)や、モデルごとの例外対応、非同期監視などを追加してください。
profiles.yml と publish_router マクロの例
# profiles.yml(抜粋)
my_project:
target: blue
outputs:
blue:
type: snowflake # 例。BigQuery/Databricks等でも同様にtargetでスキーマ分離
account: <account>
user: <user>
password: <password>
role: <role>
database: ANALYTICS
warehouse: TRANSFORMING
schema: analytics_blue
green:
type: snowflake
account: <account>
user: <user>
password: <password>
role: <role>
database: ANALYTICS
warehouse: TRANSFORMING
schema: analytics_green
-- macros/publish_router.sql
{% macro publish_router(color='green', router_schema='analytics', models=None) %}
{# colorは'blue'または'green' #}
{% set db = target.database %}
{% set base_schema = 'analytics_' ~ color %}
{# 対象モデルの解決 #}
{% if models is not none %}
{% set selected = [] %}
{% for m in models %}
{% do selected.append(graph.nodes['model.' ~ project_name ~ '.' ~ m]) %}
{% endfor %}
{% else %}
{% set selected = graph.nodes.values() | selectattr('resource_type', 'equalto', 'model') | list %}
{% endif %}
{# ビューの再作成(単体オブジェクトは原子的に置換) #}
{% for node in selected %}
{% set src = adapter.quote(db) ~ '.' ~ adapter.quote(base_schema) ~ '.' ~ adapter.quote(node.alias) %}
{% set dst = adapter.quote(db) ~ '.' ~ adapter.quote(router_schema) ~ '.' ~ adapter.quote(node.alias) %}
{% do run_query('create or replace view ' ~ dst ~ ' as select * from ' ~ src) %}
{% endfor %}
{% endmacro %}
# selectors.yml(差分ビルド用の例)
selectors:
- name: ci_modified
definition:
union:
- method: state
value: modified+
children: true
- method: fqn
value: "tests"検証はモデル単体テストに加えて、指標整合性(例: 前日比の乖離)、件数・主キー重複、重要テーブル間の行数・合計値差分などを含めると失敗の早期検知につながります。Routerの切替直後は監視を厚くし、5〜15分を重点観測とします。
ロールバックはpublish_routerをBlueに向けて再実行するだけで即時完了します。実体スキーマの中身はそのまま保持されるため、原因調査をしつつGreenを再ビルドできます。一定期間後に古いスキーマをクリーンアップする運用(タグやメタデータ管理)を合わせて設計します。
Analytics Engineer試験では、環境の分離、差分ビルド(state:modified+)、deferの意味、ロールバック戦略が頻出です。Blue/Green文脈では、ビューの置換が一般に原子的である一方、複数オブジェクトを完全同時に切替できるかはエンジン依存である点を押さえます。
主要クラウドDWHの安定的な挙動を比較します。ここでのポイントは、ポータブルに運用したいならRouterビュー方式が共通解になりやすいことです。
| 機能/性質 | Snowflake | BigQuery | Databricks (Delta) |
|---|---|---|---|
| ビューのCREATE OR REPLACE | 原子的置換(メタデータ更新)。一般的に短時間 | 原子的置換。メタデータ操作が高速 | 原子的置換。メタデータ更新で切替 |
| スキーマ(データセット)スワップ | スキーマのSWAPは不可(DB間SWAPやテーブルSWAPは提供) | データセットのスワップ不可 | スキーマスワップ不可 |
| テーブルの原子的入替 | ALTER TABLE ... SWAP WITHが利用可能 | CREATE OR REPLACE TABLE / スナップショット・コピーで対応 | CREATE OR REPLACE TABLE(Deltaのトランザクションで原子的) |
| クローン/タイムトラベル | ゼロコピーCLONEで迅速復旧可 | テーブルスナップショットで復旧可 | DeltaのTime Travelで復旧可 |
| 権限の引き継ぎ | ビューに対するGRANTは独立。再作成時のGRANT維持に注意 | ビュー再作成で権限再付与必要な場合あり | ビュー再作成時の権限維持に注意(スクリプト化推奨) |
Analytics Engineer
問題 1
dbtでBlue/Greenデプロイを実装しています。現行はanalytics_blue、候補はanalytics_greenで、利用者はanalyticsスキーマを参照します。変更されたモデルのみを候補にビルドし、テスト合格後にダウンタイムなく切替・即時ロールバック可能にしたい。最も適切な手順はどれですか?
正解: A
変更のみを候補スキーマに構築するにはstate:modified+と--deferが有効で、切替はRouterスキーマ(analytics)のビューをCREATE OR REPLACEで再公開するのがダウンタイムを最小化します。問題時は参照先をBlueに戻すだけで即時復旧できます。
権限(GRANT)は切替のたびにやり直す必要がありますか?
Routerスキーマ配下のビューに対するGRANTを固定化すれば、切替時はビューの中身(参照先)だけを置換するため、通常は追加の権限作業は不要です。ただしDWHによってはCREATE OR REPLACEで権限が外れる場合があるため、ビュー再作成後に権限検証・再付与を自動化するのが安全です。
完全な同時切替(全ビューを同一瞬間に切替)は可能ですか?
単一ビューの置換は原子的ですが、複数オブジェクトを絶対同時に入れ替えるかはエンジン機能に依存します。多くの現場ではスキーマ互換性を維持しつつ、短時間の逐次置換と監視で十分な可用性を確保します。厳密な同時性が要件なら、エンジン固有のスワップ機能や発行順制御を検討します。
--deferとstate:modified+は本番でも安全に使えますか?
はい。--stateに直近の本番アーティファクト(manifest.json/runner_artifacts)を指定し、--deferで未変更の上流を本番から解決すれば、変更分だけを候補に再構築できます。実体を破壊せずに差分ビルドできるため、Blue/Greenと相性が良いです。
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)、設定優先度...