dbt

dbt DuckDB アダプター実践ガイド:ローカル/組込みでの開発と試験対策

2026-04-19
NicheeLab編集部

DuckDB は単一ファイルまたはメモリ内で動作する組込み型データベースです。dbt-duckdb アダプターを使えば、クラウド DWH なしでローカルにモデルを検証し、高速に反復ができます。

本稿は実務と資格対策の両立を意識し、公式ドキュメントに沿った安定的な使い方に絞って、手戻りが起きやすい落とし穴を先回りで潰します。

DuckDB アダプターの位置づけと適合ユースケース

dbt-duckdb は、dbt のモデルやテスト、スナップショットを DuckDB 上で実行するためのアダプターです。DuckDB はサーバ不要で、ローカルのファイル(.duckdb)やメモリ上にデータを保持できます。これにより、開発者はネットワークやクラウド課金に依存せず、手元で素早くモデリングの反復が可能になります。

試験観点では、マテリアライズ(view / table / incremental / ephemeral)、モデル間の依存、ソース定義、テスト・スナップショットなど dbt の普遍的な概念は DuckDB でも同様に問われます。DuckDB 固有の注意点(権限管理がない、同一ファイルの併行更新は避けるなど)を理解しておくと、実務でも試験でも混乱を避けられます。

  • 適する場面: ローカル試作、学習・ワークショップ、軽量な CI、データの事前プロファイリング
  • 基本スキーマ: 既定は main。profiles.yml で schema を任意に切り替え可能
  • 権限まわり: DuckDB はサーバ型の権限制御を持たないため、dbt の grants 設定は効果が限定的
  • 併行実行: 同一 .duckdb ファイルへの同時書き込みは避け、ジョブを直列化するのが安全

プロファイル設定とローカル開発フロー

dbt で DuckDB を使うには profiles.yml にアダプター固有の設定を書きます。最小限は type、path、schema です。拡張機能(extensions)や接続時設定(settings)を加えると、HTTP/Parquet の読み取りやメモリ制限などを制御できます。

ローカル開発フローの基本は「ソース定義 → モデル(staging/marts)→ テスト → スナップショット(必要に応じて)」です。まず view で軽くつないで形を整え、確定テーブルは table で固めるのが反復に向きます。

  • path は相対パス指定が便利。CI では一時ディレクトリ配下に配置するとクリーンに回せます
  • http や S3 上のファイルを読みたい場合は、extensions に httpfs を追加
  • threads はローカル CPU に合わせて無理のない数に。DuckDB 自体も並列化するため、過度なスレッド数は逆効果になり得ます

ローカル開発の典型フロー(dbt + DuckDB)

CSV / ParquetHTTP / S3 / LocalDuckDB (file)dev.duckdbdbt run / testdbt modelsstaging / martsviews / tables(main schema)read_csv_auto() /read_parquet()compile + executeartifacts(target dir)dbt test / snapshot

最小構成の profiles.yml と dbt_project.yml

# ~/.dbt/profiles.yml
duckdb:
  outputs:
    dev:
      type: duckdb
      path: ./local/dev.duckdb
      schema: analytics
      threads: 4
      extensions:
        - httpfs
        - parquet
      settings:
        memory_limit: 2GB
  target: dev

# dbt_project.yml
name: duckdb_local_lab
version: 1.0
profile: duckdb
models:
  duckdb_local_lab:
    +materialized: view
    staging:
      +schema: staging
    marts:
      +materialized: table

モデリングとマテリアライズ戦略(DuckDB での注意点)

DuckDB 上でも dbt の標準マテリアライズ(view / table / incremental / ephemeral)が使えます。反復速度を優先するなら staging は view、確定させたいファクト・ディメンションは table が無難です。ephemeral は小さな前処理を呼び出し側へインライン展開したいときに有効です。

インクリメンタルモデルは append または delete+insert 戦略が安定です。unique_key を指定して、is_incremental() ブロックで取り込み条件を定義します。DuckDB とファイルソースを組み合わせる場合は、到着日時やファイルリストを基準に差分取り込みを設計します。

  • 試験観点: materialized の既定は adapter 依存ではなくプロジェクト設定による。モデルごとに config で上書き可能
  • グラント(grants)は DuckDB では事実上無効。設定しても影響しない点に注意
  • 同一ファイルの並列書き込みは避ける。複数ターゲットが必要ならファイルを分ける

DuckDB 向けインクリメンタルモデルの例(delete+insert)

-- models/marts/fct_orders.sql
{{ config(
    materialized='incremental',
    unique_key='order_id',
    incremental_strategy='delete+insert'
) }}

with src as (
  select * from {{ ref('stg_orders') }}
  {% if is_incremental() %}
    where updated_at > (select coalesce(max(updated_at), '1970-01-01') from {{ this }})
  {% endif %}
)

select
  order_id,
  customer_id,
  order_date,
  updated_at,
  total_amount
from src

ファイル取り込みと拡張機能の活用(httpfs / parquet)

DuckDB は関数でファイルを直接読み込めます。ローカルなら read_csv_auto() や read_parquet()、リモートなら httpfs 拡張を有効化して HTTP/HTTPS 上のオブジェクトを参照します。拡張は profiles.yml の extensions に列挙します。

実務では、外部ファイルをすぐに取り込まず、まず view で直接参照してプロファイリングする手があります。型や欠損の傾向を把握できたら、確定テーブルへ CTAS(create table as select)するモデルを追加します。これにより、反復初期の不要な I/O を抑えられます。

  • httpfs を使う場合は、URL と認証方式が環境に合っているか事前に確認する
  • ワイルドカードやディレクトリを read_parquet() に渡すと複数ファイルをまとめて読み込める
  • 試験観点: ソース定義(sources)は外部システムのメタデータ管理に有用。read_parquet() 直書きより可観測性が上がる

CSV/Parquet をビューとして参照するモデル例

-- models/staging/stg_sales_files.sql
{{ config(materialized='view') }}

with p as (
  -- ディレクトリ配下の Parquet をまとめて読み込む
  select * from read_parquet('data/sales/*.parquet')
),
cs as (
  -- リモート CSV(httpfs 拡張が有効であること)
  select * from read_csv_auto('https://example.com/sales/latest.csv')
)

select * from p
union all
select * from cs

テスト、スナップショット、CI への組み込み

dbt の汎用テスト・カスタムテストは DuckDB でもそのまま動作します。スナップショットも SQL レベルの機能のため利用可能です。開発中は dbt test を小刻みに回し、不変キーや一意制約の欠損を早期に検知します。

CI では、リポジトリ同梱の profiles.yml を使用して一時ディレクトリに .duckdb を出力します。キャッシュ前提の長時間ジョブにせず、毎回クリーンに作り直す方がトラブルが少ないです。並列ジョブで同一ファイルを書かないようジョブごとにパスを分離します。

  • 最小コマンド: dbt deps → dbt seed → dbt run → dbt test
  • state 比較を使う場合は、--state で前回成果物を渡し、変更影響だけを再実行
  • スナップショットのユニークキーと更新検知カラムは必ず明示する

GitHub Actions での軽量 CI 例(DuckDB)

name: dbt-duckdb-ci
on:
  pull_request:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - run: pip install --upgrade pip && pip install dbt-duckdb
      - name: dbt deps / seed / run / test
        env:
          DBT_PROFILES_DIR: ./.dbt
        run: |
          dbt deps
          dbt seed --threads 4
          dbt run  --threads 4
          dbt test --threads 4

プロトタイプから本番 DWH への移行(差分と落とし穴)

DuckDB で形を固めたら、Snowflake や Databricks SQL、Postgres などの DWH/DB に移すケースが多いです。その際は、接続形態、権限、同時実行、インクリメンタル戦略、型の差異に注意します。特定エンジン依存の関数はモデル層に閉じ込め、共通ロジックは macro と adapter.dispatch で抽象化すると移行が楽になります。

オブジェクト命名とクオート、スキーマの有無、時刻型の扱いは移行時の定番ハマりどころです。CI で本番アダプターを使ったモック実行を1本用意し、早い段階で差異を洗い出しましょう。

  • チェックリスト: 命名規則、スキーマ戦略、型マッピング、インクリメンタル戦略、権限・所有者
  • マクロ抽象化: read_parquet など DuckDB 固有関数は専用マクロ経由で呼ぶと差し替えやすい
  • 試験観点: モデルの可読性・再利用性(パッケージ化、マクロ化)が重視される
観点DuckDB(ローカル/組込み)Postgres(サーバ型)Snowflake(クラウド DWH)
接続形態単一プロセス/ファイル or メモリTCP 接続・常駐サーバマネージド・ウェアハウス
権限管理限定的(grants は実質無効)ロール/権限ありロール/権限・RBAC
起動/準備即時(ファイルを開くだけ)サービス起動が必要ウェアハウス起動・割当が必要
同時書込み単一プロセス推奨複数クライアントで並行可複数セッションで並行可
コストローカル実行で追加コストなしインフラ運用コスト従量課金(コンピュート/ストレージ)
増分戦略の一般度append / delete+insert が安定MERGE 含め広く一般的MERGE 戦略が一般的

問題で確認

Analytics Engineer

問題 1

ローカル環境で dbt-duckdb を使い、HTTP 上の CSV を view モデルから参照したい。正しい設定の組み合わせはどれか。

  1. profiles.yml の extensions に httpfs を追加し、モデルでは read_csv_auto('https://...') を用いる
  2. dbt_project.yml の models に httpfs: true を設定し、モデルは通常の select だけを書く
  3. profiles.yml の path を :memory: にし、モデルで external table を作成する
  4. profiles.yml の threads を 1 にし、モデルは seed 経由で取り込む

正解: A

HTTP/HTTPS のファイル参照には DuckDB の httpfs 拡張が必要です。dbt のプロジェクト設定ではなく、profiles.yml 側の extensions で有効化し、モデル内で read_csv_auto() などの関数を使って参照します。:memory: はメモリ内 DB を意味しますが、外部ファイル参照の可否とは別問題です。seed はローカル静的ファイルを取り込む仕組みで、HTTP の直接取り込みではありません。

よくある質問

dbt-duckdb で grants 設定は有効ですか?

DuckDB はサーバ型の権限モデルを持たないため、dbt の grants 設定は実質的に効果がありません。権限管理が必要な本番環境では、Snowflake や Postgres などのアダプターに切り替えて対応します。

同じ .duckdb ファイルを複数の dbt 実行で同時に更新してよいですか?

推奨されません。単一ファイルに対する同時書き込みは競合の原因になります。ジョブを直列化するか、実行ごとに別ファイルを使い分けてください。

メモリ使用量が心配です。制御できますか?

profiles.yml の settings で memory_limit などの接続時設定を指定できます。DuckDB の設定に委ねられるため、環境に合わせて適切な上限を設定してください。

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

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