Předpoklady a instalace

dbt Core vyžaduje Python 3.8+ a instaluje se přes pip. Důležité je nainstalovat nejen základní balíček, ale takékonkrétní adaptér pro váš sklad. Každý sklad má svůj vlastní adaptér, protože dialekty SQL se liší.

# 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!

Začněte s DuckDB pro místní rozvoj

Pokud nemáte okamžitý přístup k BigQuery nebo Snowflake, DuckDB je to cesta rychlejší začátek: je to vestavěná databáze, která běží přímo lokálně, nevyžaduje žádnou infrastrukturu a dbt-duckdb funguje na jakémkoli počítači. Perfektní na učení bez nákladů.

Vytvořte první projekt dbt

Příkaz dbt init vytvoří strukturu složek projektu dbt a provede vás v počáteční konfiguraci:

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

Soubor dbt_project.yml

Srdcem konfigurace projektu je dbt_project.yml. Definujte zde název projektu, verze dbt, cesty k adresářům a globální konfigurace z modelů:

# 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

Soubor profiles.yml

Vstupní přihlašovací údaje pro připojení ~/.dbt/profiles.yml (v domovském adresáři, nikdy v úložišti). Každý profil může mít více cílů (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

Konvencí je, že každý vývojář má svůj osobní vzor (např. dbt_dev_federico) aby nedocházelo ke konfliktům během paralelního vývoje.

dbt modely: Základní jednotka

Model dbt je soubor .sql v adresáři models/. Obsah je to jednoduchý SELECT — dbt se postará o vytvoření odpovídajícího pohledu nebo tabulky ve skladu.

Začněme realistickým příkladem. Předpokládejme, že máme stůl raw.orders v sklad s nezpracovanými daty z aplikace:

-- 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

Makro ref().

Makro ref() je to nejdůležitější vlastnost dbt. Když píšeš {{ ref('stg_orders') }}, dbt:

  1. Vyřeší správný název tabulky/zobrazení ve skladu pro aktuální prostředí
  2. Zaznamenejte závislost do orientovaného acyklického grafu (DAG)
  3. Zajistí, že závislý model běží jako první
-- 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

Makro source().

Pro přístup k nezpracovaným zdrojům (tabulkám nevytvořeným dbt) použijte source() místo ref(). Zdroje musí být deklarovány v souboru 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"

S tímto nastavením můžete spustit dbt source freshness ověřit to zdroje jsou aktualizovány před zahájením transformací.

Spusťte dbt: základní příkazy

# 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

Doporučená struktura šablony

Třívrstvá struktura doporučená komunitou dbt:

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

Anti-pattern: Business Logic in Staging

Pracovní šablony musí provádět pouze „hloupé“ operace: přejmenovávat sloupce, typy přetypování, deduplikovat. Obchodní logika (výpočty, agregace, spojení) přechází do mezilehlých modelů nebo marts. Pokud váš pracovní model obsahuje GROUP BY nebo více než několik vypočítaných sloupců, asi toho v té vrstvě děláš moc.

Kontrola nastavení pomocí dbt debug

Před běháním dbt run, ověřte, že připojení ke skladu funguje:

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]

Závěry a další kroky

Nakonfigurovali jsme fungující dbt projekt s tříúrovňovou strukturou (staging → střední → marts), profily připojení pro různá prostředí, deklarované zdroje s kontrolou čerstvosti a první modely s ref() e source().

Dalším krokem je udělat náš SQL dynamický pomocí Jinja: proměnné, smyčky, podmínky a znovu použitelná makra, která eliminují duplicitu kódu ve skladu.