データベース

dbt Coreの使い方:インストールからprofiles.yml・dbt build・CIまでの手順【1.12対応】

dbt Coreの使い方:インストールからprofiles.yml・dbt build・CIまでの手順【1.12対応】

dbt Coreの使い方は、2026年9月を境に入口が変わりました。pip install dbtで入るのはRustで作り直されたdbt v2で、従来のPython版を使うならdbt-coreを版指定で入れます。この記事では、2026年11月時点の公式ドキュメントとPyPIの実測をもとに、dbt-core 1.12系のインストール、dbt initとprofiles.ymlの設定、seedとrefによる最初のモデル、データテスト、dbt buildと--select、変更分だけを回すCIまでを、コピーして動かせる形で整理しました。

まとめ:dbt Coreは版を固定して入れ、dbt buildとCIで回すのが基本形

手元でdbt Coreを試すなら、Python 3.12前後のvenvにdbt-core~=1.12.0とアダプターを入れ、DuckDBで動かすのが最短です。DWHの契約もクラウドの権限も要りません。

版の固定は省けません。PyPIには2.0.0のリリース候補がすでに公開されており、正式版が出るとpip install dbt-coreの中身がdbt OSS(v2系)に変わると公式ブログが予告しています。

日々の実行はdbt runではなくdbt buildを使い、テストに落ちたモデルの下流を止めます。プルリクエストではstate:modified+で変更分と下流だけを回すと、触っていないモデルの実行時間をCIから丸ごと省けます。

PostgreSQLを使っているなら当面は1.12系で続け、SnowflakeやBigQueryで新規に始めるならv2を検討する、という分け方が2026年11月時点の結論です。

2026年11月の3系統:dbt-core 1.12・dbt v2・dbt OSS

2026年11月時点のdbt Coreには、dbt-core 1.12・dbt v2・dbt OSSという3系統があります。

手順に入る前に、どのパッケージを入れるかを決めます。名前が似ているため、ここを曖昧にすると後で環境を作り直すことになります。

pip install dbtで入るのはv2、dbt-core指定で入るのは1.12系

公式のInstall dbtは、dbtをインストールすると既定でdbt v2が入ると明記しています。2026年9月16日公開のdbtとdbt OSSの違いによれば、旧称Fusionエンジンが「dbt」、dbt Core v2が「dbt OSS」へ改称されました。PyPIで実測した3パッケージの違いは次のとおりです。

パッケージ 最新版(2026-11-11時点) ライセンス アダプター
dbt-core 1.12.6(2.0.0rc10は候補版) Apache 2.0 別途pipで導入
dbt 2.0.11 dbt独自の無償ライセンス 実行時に自動取得
dbt-oss 2.0.11 Apache 2.0 dbtリポジトリ参照

pipは既定で候補版を選ばないため、今日pip install dbt-coreを実行すると1.12.6が入ります。正式版の2.0.0が出た時点でこの挙動は変わるので、手順書やrequirements.txtには上限付きの版指定を書いておきます。

1.12系を選ぶ条件とv2へ進む条件はアダプターの対応で分かれる

Upgrading to v2(2026年10月29日更新)がv2の対応アダプターとして挙げるのは、BigQuery・Databricks・Redshift・Snowflake・ClickHouse(非公開ベータ)・Apache Spark(CLIのみのベータ)・DuckDB(CLIのみ)です。PostgreSQLとSQL Serverは一覧にありません。

判断の軸は単純です。接続先が一覧に無い、Pythonモデルや社内マクロに古い書き方が多い、Apache 2.0以外のソフトウェアを社内規程で使えない、のどれかに当たれば1.12系を使います。公式ブログによると、1.13が機能を追加する最後のマイナー版で、セキュリティとインストールの修正は通常の1年を超えて3〜5年続く見込みです。急いで移る必要はありません。

Python 3.10以上のvenv:dbt-core 1.12とアダプターの導入

ここからは1.12系の手順です。接続先には、ファイル1つで動くDuckDBを使います。

venvの作成とdbt-duckdbの導入、2.0を避ける版指定のコマンド

dbt-core 1.12.6はPython 3.10以上が必須です。仮想環境を作り、dbt-duckdbと一緒に版を固定して入れます。

# 仮想環境を作って有効化する(Windowsは dbt-env\Scripts\activate)
python3 -m venv dbt-env
source dbt-env/bin/activate

python -m pip install --upgrade pip wheel setuptools
python -m pip install "dbt-core~=1.12.0" "dbt-duckdb~=1.11.0"

dbt --version
# Core: installed: 1.12.x / Plugins: duckdb: 1.11.x と出れば成功

~=1.12.0は「1.12.0以上1.13未満」を意味します。アダプターだけを入れてもdbt-coreは依存として入りますが、dbt-duckdbの依存指定はdbt-core>=1.8.0で上限がありません。dbt-coreの行を省くと、2.0.0の正式版が出た日に別物が入ります。

DWHごとのアダプターパッケージと対応Python版の確かめ方

本番のDWHに合わせて、DuckDBの行を差し替えます。PyPIの分類子で確認した対応Python版は次のとおりです。

接続先 パッケージ(最新版) 分類子のPython版
DuckDB dbt-duckdb 1.11.1 3.10〜3.14
PostgreSQL dbt-postgres 1.11.0 3.10〜3.14
BigQuery dbt-bigquery 1.12.2 3.10〜3.13
Snowflake dbt-snowflake 1.12.5 3.10〜3.13

BigQueryとSnowflakeのアダプターは3.14を分類子に載せていません。チームで使う版はPython 3.12か3.13にそろえると、アダプターを足すときに詰まりません。版の確認はpython -m pip index versions dbt-snowflakeでも行えます。

dbt init・profiles.ymlの接続設定とdbt debugの疎通確認

パッケージが入ったら、プロジェクトの雛形と接続設定を作ります。

dbt initのフォルダとdbt_project.ymlのprofile名の対応

dbt initは、プロジェクト名を受け取って雛形を作り、入っているアダプターの中から接続先を対話で選ばせます。

dbt init shop_dbt
cd shop_dbt
# 生成物: dbt_project.yml models/example/ seeds/ macros/ snapshots/ tests/ analyses/

押さえておくのは、dbt_project.ymlのprofile: 'shop_dbt'とprofiles.ymlの最上位のキーが一致していなければ接続できない、という1点です。CIなどで対話を避けたいときは--skip-profile-setupを付け、profiles.ymlを自分で書きます。models/example/のサンプルは動作確認が済んだら消してかまいません。

profiles.ymlのtarget・outputsでdevとprodを分ける書き方

About profiles.ymlによると、1.11以降のv1は--profiles-dir、環境変数DBT_ENGINE_PROFILES_DIR、旧名のDBT_PROFILES_DIR、カレントディレクトリ、~/.dbt/の順に探します。v2は環境変数とカレントディレクトリを見ず、プロジェクト直下と~/.dbt/だけを探す点が違います。

# ~/.dbt/profiles.yml
shop_dbt:
  target: dev
  outputs:
    dev:
      type: duckdb
      path: dev.duckdb
      threads: 4
    prod:
      type: duckdb
      path: "{{ env_var('DBT_DUCKDB_PATH') }}"
      threads: 8

targetが既定の接続先で、dbt build --target prodのように実行時に切り替えます。threadsは同時に処理するモデル数で、既定は4です。DuckDBは1ファイルへの書き込みを1プロセスが握るため、手元で別のツールが同じファイルを開いていると接続に失敗します。

パスワードはenv_varとDBT_ENV_SECRET_で渡しリポジトリに置かない

SnowflakeやPostgreSQLのように認証が要る接続先では、profiles.ymlに資格情報を直書きしません。env_varで環境変数から読み、名前をDBT_ENV_SECRET_で始めると、ログに値が出た場合も*****に置き換えられます。

    prod:
      type: postgres
      host: "{{ env_var('DBT_PG_HOST') }}"
      port: "{{ env_var('DBT_PG_PORT', '5432') | as_number }}"
      user: "{{ env_var('DBT_PG_USER') }}"
      password: "{{ env_var('DBT_ENV_SECRET_PG_PASSWORD') }}"
      dbname: analytics
      schema: dbt_prod
      threads: 4

環境変数は常に文字列なので、ポートのような数値はas_numberで変換します。一方、DBT_ENV_SECRET_付きの変数にはフィルターを掛けられず、使える場所もprofiles.ymlとpackages.ymlに限られます。1.12からはカレントディレクトリの.envも自動で読まれるので、.envは必ず.gitignoreに入れてください。設定が終わったらdbt debugで、2つの設定ファイルの検証と接続テストをまとめて行います。

最初のモデルを作る:seed・ref・データテストでCSVから集計表まで

接続できたら、注文データのCSVから日別売上の表を作るところまで進めます。

seedでCSVを読み込み、本番の生データはsources.ymlで宣言する

seeds/raw_orders.csvに次のCSVを置き、dbt seedを実行するとテーブルとして読み込まれます。

order_id,customer_id,order_date,status,amount
1,101,2026-11-01,completed,4800
2,102,2026-11-01,returned,3200
3,101,2026-11-02,completed,12500
4,103,2026-11-02,pending,2100

seedは件数の少ないマスタや検証用の固定データ向けの機能です。本番では、FivetranなどのEL処理がDWHへ取り込んだテーブルをsourcesとしてmodels/sources.ymlに宣言し、{{ source('shop', 'orders') }}で参照します。取り込み側との役割分担はFivetranとdbt統合後の構成で解説しています。

stagingとmartのSQLモデルをrefでつなぎ、materializedを決める

モデルはSELECT文を1ファイル1つ書くだけです。refで上流を指定すると、dbtが依存関係を読み取って実行順を決めます。

-- models/staging/stg_orders.sql
select
    order_id,
    customer_id,
    cast(order_date as date) as order_date,
    status,
    amount
from {{ ref('raw_orders') }}

-- models/marts/fct_daily_sales.sql
{{ config(materialized='table') }}

select
    order_date,
    count(*)    as orders,
    sum(amount) as sales
from {{ ref('stg_orders') }}
where status = 'completed'
group by order_date

既定のmaterializedはviewです。参照される回数が多い集計はtableにし、行数が増え続けるファクトはincrementalを検討します。stagingとmartの責務の分け方はdbtのmarts層と3層の分け方で詳しく扱いました。

unique・not_null・accepted_valuesのYAMLテスト設定

schema.ymlに定義するのは、unique・not_null・accepted_valuesのテストです。データテストはYAMLに数行足すだけで書けます。テストの入力値をarguments:の下に置く書き方は1.10.5以降で使え、v2では必須です。新しく書くなら最初からこの形にしておきます。

# models/staging/schema.yml
version: 2
models:
  - name: stg_orders
    columns:
      - name: order_id
        data_tests:
          - unique
          - not_null
      - name: status
        data_tests:
          - accepted_values:
              arguments:
                values: ['completed', 'returned', 'pending']

キー名はdata_tests:が正式で、tests:は互換のために残っている別名です。1つのモデルに両方は書けません。列の型や必須項目を契約として固定したい場合はデータ契約とdbtの実装、統計的な分布まで検査したい場合はGreat Expectationsの実装手順が次の段階になります。

dbt runとdbt buildの違い、–selectで実行範囲を絞るコマンド集

モデルとテストがそろったら、実行のしかたを決めます。

dbt buildのDAG順:seed・model・testと失敗時の下流skip

dbt runはモデルだけを作り、テストはdbt testで別に流します。dbt buildはseed・モデル・テスト・スナップショットをDAGの順に1回で処理し、上流のテストが落ちると下流のモデルをSKIPにします。

dbt build
# 1 of 6 OK loaded seed file main.raw_orders
# ...
# Done. PASS=6 WARN=0 ERROR=0 SKIP=0 TOTAL=6

dbt runとdbt testを順に流す運用では、order_idの重複を含んだまま集計表が作られ、そのあとでテストが失敗します。間違った数字が一度ダッシュボードに出てしまう分、dbt buildの方が安全です。テストを止めずに警告だけ出したい列は、テストのconfigでseverity: warnにします。

–selectの+演算子とtag・pathで対象を絞る書き方の実例

選択構文を覚えると、開発中の待ち時間が大きく減ります。よく使う形を並べました。

dbt build --select stg_orders          # 1モデルとそのテストだけ
dbt build --select stg_orders+         # 下流も含める
dbt build --select +fct_daily_sales    # 上流も含める
dbt build --select models/marts        # フォルダ単位
dbt build --select tag:daily           # dbt_project.yml などで付けたタグ単位
dbt build --select fct_daily_sales --empty   # 0行で構文と依存だけ検証

--emptyはrefとsourceを0行に置き換えてSQLを実行するため、大きなテーブルを読まずにコンパイルエラーと列名の誤りを見つけられます。v2では旧来の--modelsや-mがエラーになるので、手順書やスクリプトは今のうちに--selectへ書き換えておきます。

state:modified+と–stateで変更分だけを回すCIの組み方

stateメソッドは、本番で最後に作ったmanifest.jsonと比べて、変更されたモデルを選びます。GitHub Actionsでの例です。

# .github/workflows/dbt-ci.yml
name: dbt-ci
on: pull_request
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      DBT_ENV_SECRET_PG_PASSWORD: ${{ secrets.DBT_PG_PASSWORD }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install "dbt-core~=1.12.0" "dbt-postgres~=1.11.0"
      - run: dbt deps
      # 本番ジョブが保存した manifest.json を prod-artifacts/ に取得しておく
      # リポジトリ直下の profiles.yml に CI 用の target「ci」を足しておく
      - run: dbt build --select "state:modified+" --state prod-artifacts --target ci --profiles-dir .

+を付けると、変更したモデルの下流まで作り直してテストします。公式ドキュメントは、--stateと--target-pathを同じ場所にしないよう注意しています。dbtが解析時にmanifest.jsonを上書きし、比較が成り立たなくなるからです。比較元はprod-artifacts/のように別フォルダへコピーして持ちます。

dbt Coreを本番で回す判断:実行基盤とdbt platformへ切り替える条件

手元で動いたあとに残る課題は、誰がいつdbt buildを実行するかです。

cron・Airflowのdbt build実行とmanifest.jsonの保管先

dbt Coreにはスケジューラが付いていません。日次の更新なら、コンテナに上記のpip行を焼き込み、cronやクラウドのジョブ実行サービスからdbt build --target prodを呼ぶ構成で足ります。取り込み処理の完了を待つ必要がある場合や、失敗時の再実行を細かく制御したい場合は、Airflowなどのワークフローエンジンから呼びます。

見落としやすいのが成果物の保管です。実行のたびにtarget/へ出力されるmanifest.jsonとrun_results.jsonをオブジェクトストレージへ保存しておかないと、前のh3のCIが比較元を失います。冪等に再実行できるパイプラインの組み方はデータパイプラインの設計判断にまとめています。

dbt Coreで続ける条件とdbt platformを選ぶ場面の分かれ目

dbt Coreで続けてよいのは、Gitとコンテナの運用に慣れたエンジニアが1人以上いて、モデルの実行が日次や時間単位のバッチで足りる場合です。ライセンス費用はかからず、実行基盤も既存のジョブ基盤に相乗りできます。

見送るのは、SQLは書けてもターミナルを使わないアナリストが開発の中心になる場合です。ブラウザ上のIDE、スケジューラ、ドキュメントの公開をdbt platformに任せた方が、実行基盤の保守に人を割かずに済みます。プランごとの費用を試算する際の参照先は、dbt 料金の全体像です。取り込みからdbtの変換、BIまでを含めたデータ基盤の設計を任せたい場合は、一創のデータ分析基盤構築・MLOps構築支援でご相談を受けています。

v2移行に備えて今やる非推奨警告の解消とrequire-dbt-versionの見直し

1.12系で続ける場合も、移行の下準備は今から進められます。v2へ移る条件は、dbt parseで出る非推奨警告をすべて解消していることです。v2では未定義のマクロや変数がdbt compileではなく解析の段階でエラーになり、使われていない設定パスも失敗扱いになります。

パッケージ側の準備も要ります。packages.ymlで入れているパッケージのrequire-dbt-versionが">=1.10.0,<3.0.0"のように2.0を含んでいるかを確かめてください。1.12で付いた--use-v2-parserフラグを使えば、移行前にv2の解析器で読めるかを試せます。

よくある質問

dbt Coreを使い始めるときによく聞かれる質問に答えます。

dbt Coreは無料で使えますか?

無料です。dbt-core 1.12系とdbt-ossはApache 2.0のオープンソースで、商用でも費用はかかりません。pip install dbtで入るv2もdbt Labsへの支払いは不要とされていますが、ライセンスはApache 2.0ではなく、dbt Mesh などの一部機能は有料のdbt platformと組み合わせて使います。費用が発生するのは接続先のDWHの利用料と、実行基盤のサーバー代です。

dbt CoreはWindowsでも使えますか?

使えます。1.12系の手順はこの記事と同じで、違いはPython 3.10以上を入れたあとのvenvの有効化がdbt-env\Scripts\activateになる点だけです。v2はwingetやPowerShellのスクリプトでも導入できます。DuckDBを使う場合、ファイルを別のアプリで開いたままだとロックで接続に失敗するので、検証中はDBeaverなどのクライアントを閉じてからdbt buildを実行してください。

dbt Coreとdbt Cloudの使い方の違いは何ですか?

モデルのSQLやYAMLの書き方は同じで、違うのは実行と開発の環境です。dbt Coreはターミナルでコマンドを打ち、スケジュール実行やドキュメントの公開を自分で用意します。dbt Cloud(現在の名称はdbt platform)が提供するのは、ブラウザのIDEとジョブ実行の画面です。どちらを選ぶかの判断軸はdbtとは:dbt Core・Cloudの選び方で整理しています。

dbt runとdbt buildはどちらを使えばよいですか?

日常の実行と本番のジョブはdbt buildを使ってください。テストが落ちたモデルの下流を作らないため、誤った集計が公開される前に止まります。dbt runが向くのは、テストを後回しにしてSQLの書き換えを素早く確かめたい開発中の場面です。その場合も--selectで対象を1モデルに絞ると、待ち時間が短くなります。

dbt Coreのバージョンアップはどうすればよいですか?

1.12系の中のパッチ更新はpython -m pip install --upgrade "dbt-core~=1.12.0" "dbt-duckdb~=1.11.0"のように、上限を保ったまま実行する方法です。1.13へ上げるときは版指定を書き換え、開発用のtargetでdbt buildが通ることを確かめてから本番に反映します。2.0への移行は非推奨警告の解消が先で、公式の移行ガイドにはdbt-autofixという書き換え支援ツールも案内されています。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.11.09 テックブログ エディオン不正アクセス第2報:カード番号の対象確認とログ・決済画面の改ざん対策
  2. 2026.11.10 テックブログ ニトリの情報漏洩:最大3,762万件の対象確認となりすまし連絡の見分け方
  3. 2026.11.10 テックブログ Claude Fable 5.2とは:料金・破壊的変更4点とFable 5.1からの移行手順【2026年11月】
  4. 2026.11.09 テックブログ LANSCOPE不正アクセス第2報:製品への影響と偽連絡の確認、停止中のライセンス認証の窓口
  5. 2025.04.30 テックブログ IMSIキャッチャー(偽基地局)とは?2Gフォールバックの手口と日本での対策

RELATED POSTS 関連記事

目次