本稿は、dbt Cloud でも dbt Core + GitHub Actions でも通用する「安定した」運用設計をベースに、PR からマージ、本番反映までの判断ポイントを具体化します。
試験対策として問われやすいキーワード(Slim CI、state artifacts、defer、run/test/build、環境分離)を、実務の設定例と併せて最短で押さえます。
dbt の CI/CD は「変更の影響範囲だけを素早く検証する CI」と「安全に本番へ昇格させる CD」を分けて設計します。基本は PR 作成で CI を自動起動し、state:modified と defer を用いて差分だけを検証。マージ後は本番ジョブがスケジュールまたはイベントで走り、安定したリソースに対して run/test を実行します。
データベース/レイクハウス側は環境・スキーマで隔離します。開発者やブランチごとの一時スキーマに CI の成果物を出力し、本番は固定スキーマ(カタログ)にのみ書き込み権限を与えます。
| 環境 | 典型的な責務 | 主な dbt コマンド |
|---|---|---|
| dev(個人/PR) | 差分検証・実験 | dbt build --select state:modified+ --defer --state path/to/prod_artifacts |
| stg(統合) | 複数 PR の結合確認・負荷検証 | dbt build --selector stg_selector |
| prod(本番) | 確定データの生成・配布 | dbt run && dbt test(あるいは dbt build) |
PR から本番までの高レベルフロー
Dev (branch)
| open PR
v
[CI Job] --- build(test) on temp schema
| status check green?
v
merge to main
|
v
[CD Job (prod)] -- run/test on prod schema
|
v
Publish docs / exposures
|
v
Consumers (BI/ML)selectors.yml の例(差分を優先的に実行)
selectors:
- name: pr_changed
definition:
union:
- method: state
value: modified
children: true
- method: tag
value: always_ci
PR が作られると CI が起動し、当該ブランチの変更モデルとその下流(+)のみを build します。参照先は defer で既存の安定版(通常は prod のアーティファクト)に差し替え、未変更部分を再計算しないのがポイントです。
CI では本番と同一のアダプタ設定(Snowflake/Databricks など)を使いながらも、出力先はブランチ専用の一時スキーマに切り替えます。成功時はステータスチェックを Git プラットフォームへ返し、レビューアはテスト通過と結果要約を確認します。
| 方式 | セットアップ難易度 | PR 連携/ステータス | Slim CI(state/defer) |
|---|---|---|---|
| dbt Cloud CI | 低(UI 中心) | 標準連携・容易 | 標準対応 |
| GitHub Actions + dbt Core | 中(YAML 設定) | Checks と連携可 | 対応可(手動設定) |
| Databricks Jobs + dbt | 中〜高(ジョブ設計) | PR 連携は工夫要 | 対応可(引数で制御) |
CI 内部フロー(概念)
N/AGitHub Actions での Slim CI 実装例
name: dbt CI (PR)
on:
pull_request:
branches: [ main ]
jobs:
slim-ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dbt-core + adapter
run: |
pip install dbt-core dbt-snowflake # or dbt-databricks
- name: Restore prod artifacts (state)
uses: actions/download-artifact@v4
with:
name: prod_artifacts
path: ./.state
- name: dbt deps
run: dbt deps
- name: dbt build (Slim CI)
env:
DBT_USER: ${{ secrets.SNOWFLAKE_USER }}
DBT_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }}
DBT_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }}
DBT_SCHEMA: pr_${{ github.event.number }}
run: |
dbt build --select state:modified+ \
--defer --state ./.state \
--target ci
- name: Upload CI artifacts
uses: actions/upload-artifact@v4
with:
name: ci_artifacts
path: target/*.jsonmain にマージされると本番系ジョブが起動します。CI では defer により既存本番を参照しましたが、本番ジョブでは実際の prod 用接続・スキーマへ出力します。スケジュール駆動とイベント駆動の併用も現実的です(高頻度モデルはイベント、重い集計はスケジュール)。
本番では run と test を明確に分けるか、build 一発でまとめるかはチームの方針次第です。重要なのは、失敗時に部分成功を残したままにしないこと、アーティファクトを確実に保存して次回の state に使うことです。
| 工程 | 目的 | 例 |
|---|---|---|
| seed | 参照マスタ投入 | 小規模 CSV を idempotent にロード |
| snapshot | 履歴管理(SCD2) | 更新検出キーで upsert |
| build(run+test) | 本体生成と検証 | 重大テストでフェイル・ファスト |
| docs | メタ更新 | dbt docs generate / exposures 反映 |
CD のシンプルな実行順序
N/A本番ジョブのコマンド例(順序の分離)
dbt deps
# 必要に応じて seed / snapshot
# dbt seed --full-refresh
# dbt snapshot
# 変更中心の実行(十分に安定運用ならフル実行も可)
dbt run --select state:modified+
dbt test --select state:modified+
# アーティファクト保存(ワークフロー側で target/*.json を保管)CI の安全性はスキーマ(またはカタログ)隔離で決まります。PR ごとに一時スキーマを作り、CI 終了後はクリーンアップします。Snowflake なら ROLE/WAREHOUSE/SCHEMA を分け、Databricks Unity Catalog なら catalog.schema を明確に分離します。
スキーマ名はブランチや PR 番号をエンコードして衝突と不正文字を避けます。dbt の generate_schema_name マクロを上書きすれば、安全な命名をチーム共通ルールにできます。
| プラットフォーム | 隔離単位 | 注意点 |
|---|---|---|
| Snowflake | データベース/スキーマ/ロール/ウェアハウス | 本番ロールは DROP/CREATE 制限、CI は専用ウェアハウス |
| Databricks (Unity Catalog) | カタログ/スキーマ/権限 | prod catalog を read-only、CI は dev catalog のみ書込 |
| その他(Postgres/BigQuery など) | スキーマ/データセット | コスト・クォータ制御とクリーンアップの自動化 |
隔離イメージ(概念)
N/Aschema 命名マクロ例(ブランチ名を安全化)
{% macro generate_schema_name(custom_schema_name, node) -%}
{%- set raw = env_var('GIT_BRANCH', 'pr') | lower -%}
{%- set safe = re.sub('[^a-z0-9_]', '_', raw) -%}
{%- set prefix = 'ci_' ~ safe[0:20] -%}
{{ return(prefix) }}
{%- endmacro %}
品質ゲートは dbt test の重大失敗で PR を止める仕組みです。unique/not_null/accepted_values などの一般的テストは CI でも有効で、重い検査(行数大、統計的比較など)はステージングで実施するとバランスが取れます。
アーティファクト(manifest.json/run_results.json)は必ず保存し、次回 CI の state として参照します。これにより Slim CI が成立し、未変更領域の再計算を避けられます。ドキュメント(catalog.json)や exposures も同時に更新し、下流利用者への可視性を担保します。
| テスト種別 | 実行タイミング | 失敗時の扱い |
|---|---|---|
| 一般(unique/not_null) | CI(PR) | PR をブロック |
| リファレンシャル/関数的 | CI or stg | 重大はブロック、軽微は警告でも可 |
| 回帰・統計比較 | stg/prod | 要レビューで運用判断 |
アーティファクトの流れ(概念)
N/Aschema.yml のテスト例(抜粋)
version: 2
models:
- name: fct_orders
tests:
- unique:
column_name: order_id
- not_null:
column_name: order_id
- relationships:
to: ref('dim_customer')
field: customer_id
本番失敗時は、まず直近のコミットをリバートして再実行します。テーブル更新の失敗で中途半端な状態が懸念される場合は、ブルー/グリーン(next スキーマに構築→ビュー切替)で可視層を安全に入れ替える設計が有効です。
権限と破壊的変更を分離し、drop や full-refresh はメンテナンスウィンドウに限定。スナップショットは本番のみで運用し、CI では通常スキップします。
| シナリオ | 検出/兆候 | 対処 |
|---|---|---|
| 重大テスト失敗 | CI ステータス赤 | 修正コミット or クローズ |
| 本番ジョブ一部失敗 | run_results で失敗ノード | リトライ or リバート後に再実行 |
| スキーマ互換性崩れ | contracts/下流エラー | ビュー切替で猶予確保→後方互換修正 |
ブルー/グリーン切替(概念)
N/Aビュー切替の簡易スクリプト例(SQL)
-- next スキーマで build 済みを想定
-- 可視スキーマのビューを next へ切替
create or replace view prod.visible.fct_orders as
select * from prod_next.fct_orders;
Analytics Engineer
問題 1
PR ベースの Slim CI を設計しています。未変更の上流モデルは本番の安定版を参照しつつ、変更モデルとその依存のみを検証したい。最も適切な dbt コマンドはどれですか?
正解: A
Slim CI の定石は state:modified+ で差分と下流を対象にし、defer で未変更の参照先を既存(通常は prod)のアーティファクトに委譲します。--state で参照する manifest.json 等の保存場所を指定します。
Slim CI で使う state アーティファクトはどこに置けばよいですか?
本番ジョブの target 配下に生成される manifest.json/run_results.json をジョブ終了時に永続ストレージへ保存し、CI 実行時にダウンロードして --state で参照します。dbt Cloud では環境のアーティファクト参照が容易で、GitHub Actions 等では upload/download-artifact か外部ストレージ(S3/GCS/DBFS 等)を使います。
Snowflake や Databricks で CI を安全に動かす権限設計は?
CI 専用ロール(またはサービスプリンシパル)を用意し、書込先は開発/CI 用のスキーマ(またはカタログ)に限定します。本番スキーマへの CREATE/DROP は禁止し、SELECT のみ許可。ウェアハウス/クラスターも CI 用に分離してコストと影響範囲を管理します。
CI で snapshot や重い seed は実行すべきですか?
通常は実行しません。CI の目的は変更の妥当性と互換性の即時確認であり、スナップショットや大規模 seed は本番/ステージングのバッチに回します。必要なら軽量サンプルに切替えるか、CI 用タグで除外/限定実行します。
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)、設定優先度...