jaffle_shopでdbt Fusionを実践してみた
はじめに
dbt Labs が2025年5月に発表した dbt Fusion を試してみました。
「Rustで書き直された」「30倍高速」「真のSQLコンパイラ」などのキャッチコピーが並んでいて、気になってはいたものの手を出せていませんでした。
2026年4月のアップデートで DuckDB対応がパブリックベータ に入ったこともあり、ローカルで気軽に試せるようになったので、おなじみ jaffle_shop を使って実際に動かしてみたいと思います。
dbt Fusion とは?
一言で言うと、dbt の次世代実行エンジンです。
従来の dbt Core は Python 製でしたが、Fusion は Rust で完全に書き直されており、dbt Core とはコードを一切共有していません。
主な特徴は以下のとおりです。
| 項目 | dbt Core | dbt Fusion |
|---|---|---|
| 言語 | Python | Rust |
| SQLの扱い | テキストとしてレンダリング | SQLとして理解(真のコンパイラ) |
| パース速度 | ベースライン | 最大30倍高速 |
| エラー検知 | 実行後 | コンパイルフェーズで検知 |
| 配布形態 | Python パッケージ | 単一バイナリ |
特に「SQLを理解する」という部分が革新的で、ウェアハウスで実際にクエリを投げる前のコンパイルフェーズでカラムレベルのエラーを検知してくれます。
インストール
まずは dbt Fusion 本体をインストールします。Python 環境は不要で、インストールスクリプトを実行するだけです。
curl -fsSL https://public.cdn.getdbt.com/fs/install/install.sh | sh -s -- --update
exec $SHELL
インストールできたらバージョンを確認してみましょう。
dbt --version
dbt-fusion 2.0.0-preview.173
dbt-fusion という表示が得られればOKです。
jaffle_shop プロジェクトのセットアップ
プロジェクトの初期化
Fusion では dbt init コマンドで jaffle_shop のサンプルプロジェクトを自動生成できます。
dbt init --project-name jaffle_shop --sample jaffle-shop
cd jaffle_shop
実行すると、使用するデータベースアダプタを対話形式で聞かれます。今回は DuckDB を選択します。
生成されたディレクトリ構成はこんな感じです。
jaffle_shop/
├── dbt_project.yml
├── packages.yml
├── models/
│ ├── staging/
│ │ ├── __sources.yml
│ │ ├── stg_customers.sql
│ │ ├── stg_locations.sql
│ │ ├── stg_order_items.sql
│ │ ├── stg_orders.sql
│ │ ├── stg_products.sql
│ │ └── stg_supplies.sql
│ └── marts/
│ ├── customers.sql
│ ├── locations.sql
│ ├── order_items.sql
│ ├── orders.sql
│ ├── products.sql
│ └── supplies.sql
└── seeds/
├── raw_customers.csv
├── raw_items.csv
├── raw_orders.csv
├── raw_products.csv
├── raw_stores.csv
└── raw_supplies.csv
よくある jaffle_shop(customers・orders・payments の3テーブル)よりもモデルが多いですね。架空のカフェのデータとして、商品・店舗・注文明細なども含まれています。
DuckDB の設定
dbt init で DuckDB を選択すると ~/.dbt/profiles.yml に設定が追記されます。内容はこんな感じです。
jaffle_shop:
target: dev
outputs:
dev:
type: duckdb
path: jaffle_shop.duckdb
プロジェクトルートに profiles.yml を置いた場合は、~/.dbt/profiles.yml より優先して読み込まれます。チームで同じ設定を共有したい場合などはプロジェクトルートに置くのが便利です。
DuckDB はファイルベースなので、接続設定がとてもシンプルですね。Snowflake や BigQuery のような認証設定が不要なのでローカルでの試行錯誤に最適です。
依存パッケージのインストール
dbt deps
Installing dbt-labs/dbt_utils: 1.3.3
Installed 1 package
Finished 'deps' successfully [1.8s]
ビルド実行
さっそくビルドしてみましょう。
dbt build
dbt build は seed の投入 → モデルのビルド → テストの実行をまとめてやってくれます。
Running with dbt-fusion 2.0.0-preview.173
Succeeded [ 0.07s] seed main_raw.raw_customers (table)
Succeeded [ 0.07s] seed main_raw.raw_orders (table)
...
Succeeded [ 0.01s] model main.customers (table)
Passed [ 0.00s] test main_dbt_test__audit.unique_customers_customer_id
...
Finished 'build' successfully for target 'dev' [3.4s]
Processed: 12 models | 27 tests | 6 seeds | 3 unit tests
Summary: 48 total | 48 success
3秒ちょっとで seed・モデル・テスト・ユニットテスト全48件が完了しました。速い!
dbt Fusion ならではの機能を試す
静的解析によるカラムエラー検知
Fusion の目玉機能が静的解析です。dbt_project.yml に +static_analysis: strict が設定されており、SQLをウェアハウスで実行する前のコンパイルフェーズでエラーを検知してくれます。
実際に試してみましょう。models/marts/customers.sql に存在しないカラムを追加してみます。
select
customers.*,
non_existent_column, -- 存在しないカラム
...
この状態で dbt run --select customers を実行すると、
dbt run --select customers
error: dbt0227: No column non_existent_column found.
Available are: customer_orders_summary.is_repeat_buyer,
customer_orders_summary.lifetime_spend, customers.customer_name ...
--> models/marts/customers.sql:38:9
DuckDB にクエリを投げる前にエラーが検知されました。エラーメッセージに「利用可能なカラム名の候補」まで表示されるのが親切ですね。
dbt parse でプロジェクト構造を検証
dbt parse コマンドはモデルのコンパイルや実行を行わずに、プロジェクト全体の構文・参照関係を検証します。
dbt parse
Finished 'parse' successfully for target 'dev' [1.2s]
ref() で存在しないモデルを参照していたりすると、この段階でエラーになります。
error: dbt1048: Ref 'non_existent_model' not found in project.
--> models/staging/stg_customers.sql:6:19
ウェアハウスに接続せずに参照関係の整合性だけをチェックできるので、CI/CD に組み込んで本番実行前のバリデーションに使えそうです。
--select フラグで特定モデルのみ実行
特定のモデルだけ実行したい場合は --select を使います。
# 特定のモデルのみ
dbt run --select stg_customers
# 上流の依存モデルも含めて実行
dbt run --select +customers
+customers のように + を前に付けると、上流の依存モデルもまとめて実行してくれます。
Succeeded [ 0.02s] model main.stg_customers (view)
Succeeded [ 0.02s] model main.stg_order_items (view)
Succeeded [ 0.03s] model main.stg_orders (view)
Succeeded [ 0.04s] model main.stg_products (view)
Succeeded [ 0.04s] model main.stg_supplies (view)
Succeeded [ 0.03s] model main.order_items (table)
Succeeded [ 0.64s] model main.orders (table)
Succeeded [ 0.03s] model main.customers (table)
customers が依存している上流モデルが全て実行されました。
dbt list でモデル一覧を確認
dbt list --resource-type model
jaffle_shop.marts.customers
jaffle_shop.marts.locations
jaffle_shop.marts.order_items
jaffle_shop.marts.orders
jaffle_shop.marts.products
jaffle_shop.staging.stg_customers
jaffle_shop.staging.stg_locations
jaffle_shop.staging.stg_order_items
jaffle_shop.staging.stg_orders
jaffle_shop.staging.stg_products
jaffle_shop.staging.stg_supplies
jaffle_shop.marts.supplies
プロジェクトが大きくなってきたときに、どんなモデルがあるか確認するのに便利です。jaffle_shop.marts.customers のように プロジェクト名.レイヤー.モデル名 の形式で出力されます。
VS Code との連携
dbt Fusion は VS Code 拡張機能(dbt Labs Inc. 製)との連携も強化されています。
拡張機能をインストールして jaffle_shop フォルダを開くと、以下の機能が使えるようになります。
-
IntelliSense:
{{ ref('と入力すると参照できるモデルが補完される - インラインエラー: タイピング中に SQL エラーがエディタ上に表示される
- Hover Insights: モデル名にカーソルを当てるとカラム情報などが表示される
- Go-to-definition: モデル名を Cmd クリックで定義元にジャンプ
IDEの補完が効くと開発体験がぐっと上がりますね。
dbt Core との互換性について
dbt Fusion を試す上で気になるのが、既存プロジェクトとの互換性です。
主な注意点をまとめておきます。
マニフェストの非互換
Fusion は v20 マニフェストを生成しますが、dbt Core は v12 です。state:modified や --defer を使っている場合、全環境を同時にアップグレードする必要があります。
厳格なパース
Fusion はより厳格にパースを行うため、dbt Core では問題なかったコードがエラーになるケースがあります。たとえば存在しないマクロの呼び出しや未定義変数の参照などです。
逆に言うと、これらを直すことでコードの品質が上がるとも言えますね。
まとめ
今回は jaffle_shop を使って dbt Fusion を試してみました。
Rust 製の単一バイナリで Python 環境不要、DuckDB でローカル完結、コンパイルフェーズでのカラムレベルエラー検知、、と開発体験が大幅に改善されていました。
特に静的解析によるエラー検知は、ウェアハウスへの無駄なクエリを減らしつつ問題を早期に発見できるので、CI に組み込む使い方が良さそうだと感じました。
2026年4月時点ではまだプレビュー段階ですが、GA に向けて着々と機能が揃ってきています。新規プロジェクトから Fusion を採用するのが良いスタートラインかなと思っています。
Discussion