前提条件とインストール

dbt Core には Python 3.8 以降が必要で、pip 経由でインストールされます。重要なのはインストールすることです 基本パッケージだけでなく、特定のアダプター あなたの倉庫に。 SQL 言語が異なるため、各ウェアハウスには独自のアダプターがあります。

# Installa dbt Core con l'adapter per PostgreSQL (ottimo per iniziare in locale)
pip install dbt-postgres

# Per BigQuery
pip install dbt-bigquery

# Per Snowflake
pip install dbt-snowflake

# Per DuckDB (ideale per sviluppo locale senza infrastruttura)
pip install dbt-duckdb

# Verifica l'installazione
dbt --version
# Core:
#   - installed: 1.9.0
#   - latest:    1.9.0 - Up to date!

ローカル開発用の DuckDB を使ってみる

BigQuery または Snowflake にすぐにアクセスできない場合は、 アヒルDB それが方法です すぐに始めることができます。これはローカルで直接実行される組み込みデータベースです。 インフラストラクチャは必要なく、dbt-duckdb はどのマシンでも動作します。学習に最適 費用をかけずに。

最初の dbt プロジェクトを作成する

コマンド dbt init dbt プロジェクトのフォルダー構造を作成し、ガイドします。 初期設定では:

dbt init jaffle_shop

# dbt chiederà:
# 1. Quale database vuoi usare? (postgres/bigquery/snowflake/...)
# 2. [Per postgres] host, port, user, password, database, schema

# La struttura creata:
jaffle_shop/
├── dbt_project.yml          # configurazione principale
├── README.md
├── analyses/               # query ad hoc (non materializzate)
├── macros/                 # funzioni Jinja riutilizzabili
├── models/
│   └── example/            # modelli di esempio (da eliminare)
├── seeds/                  # CSV statici
├── snapshots/              # snapshot per SCD
└── tests/                  # test SQL singolari

dbt_project.yml ファイル

プロジェクト構成の中心となるのは、 dbt_project.yml。ここで定義します プロジェクト名、dbt バージョン、ディレクトリ パス、およびグローバル構成 モデルの:

# dbt_project.yml
name: 'jaffle_shop'
version: '1.0.0'

# Versione minima di dbt richiesta
require-dbt-version: ">=1.8.0"

# Percorso del profile da usare (in profiles.yml)
profile: 'jaffle_shop'

# Directory dei modelli
model-paths: ["models"]
analysis-paths: ["analyses"]
test-paths: ["tests"]
seed-paths: ["seeds"]
macro-paths: ["macros"]
snapshot-paths: ["snapshots"]

# Dove salvare i log e i target compilati
target-path: "target"
log-path: "logs"
clean-targets: ["target", "dbt_packages"]

# Configurazione dei modelli per directory
models:
  jaffle_shop:
    # Tutti i modelli del progetto sono view per default
    +materialized: view

    staging:
      # I modelli in staging/ sono sempre view
      +materialized: view
      +schema: staging          # savedano in schema 'staging'

    marts:
      +materialized: table      # I marts sono table per performance
      +schema: marts

profiles.yml ファイル

接続資格情報が入ります ~/.dbt/profiles.yml (ホームディレクトリ内で、 一度もない リポジトリ内)。各プロファイルには複数のターゲット (dev、staging、prod) を含めることができます。

# ~/.dbt/profiles.yml
jaffle_shop:
  target: dev                    # target di default

  outputs:
    dev:
      type: postgres
      host: localhost
      port: 5432
      user: "{{ env_var('DB_USER') }}"      # usa variabili d'ambiente
      password: "{{ env_var('DB_PASSWORD') }}"
      dbname: jaffle_shop_dev
      schema: dbt_dev_federico   # schema personale per sviluppo
      threads: 4

    prod:
      type: postgres
      host: "{{ env_var('PROD_DB_HOST') }}"
      port: 5432
      user: "{{ env_var('PROD_DB_USER') }}"
      password: "{{ env_var('PROD_DB_PASSWORD') }}"
      dbname: jaffle_shop_prod
      schema: dbt_prod
      threads: 8

慣例として、各開発者には個人的なパターンがあります(例: dbt_dev_federico) 並行開発中の競合を避けるため。

dbt モデル: 基本ユニット

dbt モデルはファイルです .sql ディレクトリ内で models/。内容 これは単純な SELECT です。dbt はウェアハウス内に対応するビューまたはテーブルを作成します。

現実的な例から始めましょう。テーブルがあるとします raw.orders で アプリケーションからの生データを含むウェアハウス:

-- models/staging/stg_orders.sql
-- Staging model: rinomina, casta, pulisce — nessuna logica di business

WITH source AS (
    SELECT * FROM {{ source('raw', 'orders') }}   -- 'source' punta alla sorgente raw
),

renamed AS (
    SELECT
        id                                         AS order_id,
        user_id                                    AS customer_id,
        order_date                                 AS created_at,
        status,
        CAST(amount AS DECIMAL(10,2))              AS total_amount,
        LOWER(payment_method)                      AS payment_method,
        _loaded_at                                 AS loaded_at    -- metadata pipeline
    FROM source
    WHERE id IS NOT NULL                           -- filtra record corrotti
)

SELECT * FROM renamed

ref() マクロ

マクロ ref() これは dbt の最も重要な機能です。書くとき {{ ref('stg_orders') }}、dbt:

  1. 現在の環境のウェアハウス内のテーブル/ビューの正しい名前を解決します。
  2. 有向非巡回グラフ (DAG) に依存関係を記録する
  3. 依存モデルが最初に実行されるようにする
-- models/marts/finance/orders_monthly.sql
-- Usa ref() per dipendere da stg_orders

WITH orders AS (
    SELECT * FROM {{ ref('stg_orders') }}          -- dbt risolve automaticamente lo schema
),

monthly_aggregated AS (
    SELECT
        DATE_TRUNC('month', created_at)            AS month,
        payment_method,
        COUNT(*)                                   AS order_count,
        SUM(total_amount)                          AS gross_revenue,
        AVG(total_amount)                          AS avg_order_value,
        COUNT(DISTINCT customer_id)                AS unique_customers
    FROM orders
    WHERE status = 'completed'
    GROUP BY 1, 2
)

SELECT * FROM monthly_aggregated

source() マクロ

生のソース (dbt によって作成されていないテーブル) にアクセスするには、次を使用します。 source() の代わりに ref()。ソースはファイル内で宣言する必要があります sources.yml:

# models/staging/sources.yml
version: 2

sources:
  - name: raw                    # nome del source group
    database: raw_db             # database nel warehouse
    schema: public               # schema nel warehouse
    tables:
      - name: orders
        description: "Ordini grezzi dall'applicazione"
        loaded_at_field: _loaded_at    # campo per freshness check
        freshness:
          warn_after: {count: 12, period: hour}
          error_after: {count: 24, period: hour}
      - name: customers
        description: "Clienti grezzi dall'applicazione"

この設定により、実行できます dbt source freshness それを確認するために ソースは変換を開始する前に更新されます。

dbt の実行: 基本コマンド

# Esegui tutti i modelli (materialization nel warehouse)
dbt run

# Esegui solo i modelli staging
dbt run --select staging

# Esegui un singolo modello e tutte le sue dipendenze (+)
dbt run --select +orders_monthly

# Esegui tutti i test definiti nello schema YAML
dbt test

# Testa solo un modello specifico
dbt test --select stg_orders

# Compila i modelli senza eseguirli (utile per debug)
dbt compile

# Verifica freshness delle sorgenti
dbt source freshness

# Genera e serve la documentazione
dbt docs generate
dbt docs serve                  # apre http://localhost:8080

推奨されるテンプレート構造

dbt コミュニティが推奨する 3 層構造:

models/
├── staging/                    # Layer 1: vicino alla sorgente
│   ├── sources.yml            # dichiarazione sorgenti
│   ├── schema.yml             # test + documentazione
│   ├── stg_orders.sql
│   ├── stg_customers.sql
│   └── stg_products.sql
├── intermediate/               # Layer 2: join complessi (opzionale)
│   ├── int_orders_enriched.sql # join ordini + clienti
└── marts/                      # Layer 3: pronti per consumo
    ├── finance/
    │   ├── schema.yml
    │   ├── orders_monthly.sql
    │   └── revenue_by_country.sql
    └── marketing/
        └── customer_cohorts.sql

アンチパターン: ステージングにおけるビジネス ロジック

ステージング テンプレートは、列名の変更、型のキャスト、 重複を排除します。ビジネス ロジック (計算、集計、結合) は中間モデルに入ります。 またはマート。ステージング モデルに GROUP BY または複数の計算列がある場合、 おそらくその層でやりすぎているのでしょう。

dbt デバッグでセットアップを確認する

走る前に dbt run、ウェアハウス接続が機能していることを確認します。

dbt debug

# Output atteso:
# Configuration:
#   profiles.yml file [OK found and valid]
#   dbt_project.yml file [OK found and valid]
# Required dependencies:
#  - git [OK found]
# Connection:
#   host: localhost
#   port: 5432
#   user: federico
#   database: jaffle_shop_dev
#   schema: dbt_dev_federico
#   [OK connection ok]

結論と次のステップ

3 レベル構造 (ステージング → 中間→マート)、さまざまな環境の接続プロファイル、宣言されたソース 鮮度チェック機能付きと最初のモデル ref() e source().

次のステップは、Jinja を使用して SQL を動的にすることです: 変数、ループ、条件 ウェアハウス内のコードの重複を排除する再利用可能なマクロ。