Vai al contenuto principale
dbt project structure - immagine ufficiale della lezione su GinnyTech, creata da AD

dbt fundamentals e project structure

dbt fundamentals e project structure. Lezione su come configurare e strutturare un progetto dbt.

AD
Creato da Andrii Dyshkantiuk
Lezione 162 / 216 Livello: Avanzato Durata: 22 min Prerequisiti: 1

Cosa imparerai

  • Comprendere il problema analitico e il contesto decisionale
  • Applicare esempi, metriche e controlli a casi reali

dbt fundamentals e project structure

Un progetto dbt inizia bene quando fonti, modelli, naming, cartelle e ambienti rendono chiara la direzione del lavoro. dbt fundamentals e project structure imposta la struttura che evita di trasformare ogni nuova metrica in una query isolata e difficile da mantenere.

Una scena da cui partire

Leggi la lezione come impostazione delle fondamenta. Un repository dbt ordinato comunica intenzione: da dove arriva il dato, quale trasformazione subisce e quale modello è pronto per consumo business.

  • Contesto: Quale vincolo tecnico decide il disegno?
  • Metodo: Quale controllo ti direbbe che il risultato è affidabile?
  • Applicazione: Quale trade-off racconteresti prima di mettere in produzione?

L’anatomia di un progetto dbt

Un progetto dbt è un albero di directory e file che seguono convenzioni precise. Ecco la struttura minima:

my_dbt_project/
├── dbt_project.yml          ← Il cuore: nome, versione, profili, paths
├── packages.yml             ← Dipendenze esterne (dbt_utils, audit_helper...)
├── profiles.yml             ← Connessioni ai warehouse (o in ~/.dbt/)
├── models/
│   ├── staging/
│   │   └── stripe/
│   │       ├── src_stripe.yml       ← Source definitions
│   │       └── stg_stripe__payments.sql
│   ├── intermediate/
│   │   └── int_daily_customer_revenue.sql
│   └── marts/
│       ├── finance/
│       │   ├── mrt_finance__monthly_pnl.sql
│       │   └── mrt_finance.yml       ← Test + docs
│       └── marketing/
├── seeds/                    ← CSV statici caricati come tabelle
├── snapshots/                ← SCD type-2 per storicizzare cambiamenti
├── tests/                    ← Test singolari SQL
├── macros/                   ← Funzioni Jinja riusabili
├── analyses/                 ← Query ad-hoc non materializzate
└── docs/                     ← Documentazione custom (opzionale)

dbt_project.yml: il file di configurazione

Questo file definisce l’identità del progetto e le configurazioni globali:

name: 'my_analytics'
version: '1.0.0'
config-version: 2

profile: 'my_snowflake_profile'   # riferimento a profiles.yml

model-paths: ["models"]
seed-paths: ["seeds"]
snapshot-paths: ["snapshots"]
test-paths: ["tests"]
macro-paths: ["macros"]

clean-targets:
  - "target"
  - "dbt_packages"

# Configurazioni per modello
models:
  my_analytics:
    staging:
      +materialized: view        # leggeri, non persistono su disco
      +schema: staging
    intermediate:
      +materialized: table       # più pesanti, ma servono a più consumer
      +schema: intermediate
    marts:
      +materialized: table
      +schema: marts

La direttiva +materialized è cruciale:

  • View: il modello è una vista SQL. Non occupa storage, sempre fresca, ma viene rieseguita a ogni query. Usa per staging e modelli leggeri usati raramente.
  • Table: il modello è una tabella fisica. Ricostruita a ogni dbt run. Più veloce da leggere, occupa storage.
  • Incremental: solo le nuove righe vengono aggiunte alla tabella, il resto è intatto. Usa per tabelle grandi (>100M righe) dove ricostruire tutto è troppo costoso.
  • Ephemeral: il modello è una CTE inline, mai materializzato. Esiste solo dentro la query che lo referenzia. Usa per trasformazioni intermedie leggere.

Sources e refs: come i modelli si connettono

dbt usa due funzioni Jinja fondamentali per gestire le dipendenze:

source() — per leggere dati grezzi dal warehouse (tabelle create da Fivetran, Airbyte, o EL pipeline):

# models/staging/stripe/src_stripe.yml
version: 2
sources:
  - name: stripe
    database: raw_data
    schema: stripe
    tables:
      - name: payments
        loaded_at_field: _etl_loaded_at
        freshness:
          warn_after: {count: 12, period: hour}
          error_after: {count: 24, period: hour}
-- models/staging/stripe/stg_stripe__payments.sql
SELECT
  id AS payment_id,
  amount / 100.0 AS amount_eur,
  created AS payment_date,
  status
FROM {{ source('stripe', 'payments') }}

ref() — per referenziare altri modelli dbt:

-- models/intermediate/int_daily_customer_revenue.sql
SELECT
  c.customer_id,
  DATE(o.payment_date) AS revenue_date,
  SUM(o.amount_eur) AS daily_revenue
FROM {{ ref('stg_stripe__customers') }} c
JOIN {{ ref('stg_stripe__payments') }} o
  ON c.customer_id = o.customer_id
GROUP BY c.customer_id, DATE(o.payment_date)

Il vero potere di source() e ref() è il lineage automatico: dbt sa esattamente quali modelli dipendono da quali, e può:

  • Eseguire i modelli nell’ordine corretto (dbt run)
  • Generare il DAG di dipendenze (dbt docs generate)
  • Testare la freschezza dei dati sorgente (dbt source freshness)

Il workflow dbt: i quattro comandi essenziali

Ogni analytics engineer passa il 90% del tempo su quattro comandi:

dbt run          → Esegue tutti i modelli nell'ordine del DAG
dbt test         → Esegue tutti i test e riporta i fallimenti
dbt docs generate→ Genera documentazione HTML + lineage graph
dbt build        → run + test + seed + snapshot in un colpo solo

Un quinto comando è entrato nel workflow standard con l’adozione di CI:

dbt build --select state:modified+ --defer --state ./target/

Questo comando, eseguito in CI, costruisce e testa solo i modelli modificati (e quelli a valle), non l’intero progetto.

Caso reale: l’adozione di dbt in una logistica company

Una azienda di logistica italiana con 800 camion e 1500 autisti aveva dati operativi in PostgreSQL (tracking GPS) e dati finanziari in un ERP Oracle. Il team dati (3 persone) usava script Python + SQL per creare report, con conseguenti disallineamenti.

L’adozione di dbt seguì questo percorso in 8 settimane:

  • Settimana 1-2: Configurazione di dbt Cloud connesso a Snowflake. Definizione delle source (PostgreSQL → Fivetran → Snowflake; Oracle → Airbyte → Snowflake).

  • Settimana 3-4: Costruzione dei modelli staging (15 modelli, 1:1 con le tabelle sorgente). Zero logica di business, solo rinominazione e casting.

  • Settimana 5-6: Costruzione di 8 modelli intermediate con la logica di business critica: calcolo del costo per km, definizione di viaggio, segmentazione autisti per efficienza.

  • Settimana 7: Costruzione dei marts per i tre consumatori: operations dashboard (Tableau), finance report (Excel), data science (notebook).

  • Settimana 8: Test e CI. 140 test automatici, GitHub Actions configurato per dbt build --select state:modified+.

Il direttore operations, scettico inizialmente, divenne il maggiore sponsor dopo aver visto che poteva avere il costo per km aggiornato ogni ora invece che ogni lunedì.

Jinja in dbt: non è solo SQL

dbt estende SQL con Jinja, un template engine Python. I costrutti più usati:

-- Cicli
{% for country in ['IT', 'FR', 'DE', 'ES'] %}
  SUM(CASE WHEN country = '{{ country }}' THEN revenue ELSE 0 END) AS revenue_{{ country }},
{% endfor %}

-- Condizioni
{% if target.name == 'prod' %}
  WHERE is_test = FALSE
{% endif %}

-- Variabili
{% set threshold = 1000 %}
SELECT * FROM orders WHERE amount > {{ threshold }}

Il Jinja rende dbt un linguaggio di programmazione, non solo un runner SQL. Permette di eliminare il copia-incolla, rendere i modelli parametrici, e adattare la logica all’ambiente (dev/staging/prod).


Riferimenti:

  • dbt Labs. (2024). “dbt Project Structure.” dbt Developer Hub.
  • Taylor, J. (2022). “dbt Jinja Functions and Best Practices.” dbt Developer Blog.
  • Reis, J. & Housley, M. (2022). Fundamentals of Data Engineering. O’Reilly.

Controllo di qualità

Prima di usare dbt fundamentals e project structure in una decisione, controlla sempre completezza, duplicati, timezone, definizioni cambiate e segmenti esclusi. Molte analisi apparentemente sofisticate falliscono perché il dato di partenza misura un comportamento diverso da quello che il team crede di osservare.

Problema reale

Nel dominio di analytics engineering, dbt fundamentals e project structure serve a risolvere questo problema: trasformare dati grezzi in modelli testati, documentati e riusabili dal business. La lezione non va trattata come teoria isolata, ma come un modo per migliorare una scelta concreta con dati, assunzioni esplicite e controlli minimi.

Obiettivo operativo: Comprendere il problema analitico e il contesto decisionale; Applicare esempi, metriche e controlli a casi reali. Se alla fine non sai indicare quale decisione cambia, quale dato osservi e quale errore vuoi evitare, la lezione non è ancora diventata competenza applicata.

Modello concettuale

FaseCosa chiarireOutput
DomandaQuale scelta reale deve migliorare?Decisione da prendere
MisuraQuale segnale osservabile rappresenta il problema?Metrica o dato sorgente
ControlloQuale baseline rende il risultato interpretabile?Confronto credibile
AzioneChe cosa cambia dopo l’analisi?Prossimo passo operativo

Il modello concettuale è intenzionalmente semplice: decisione, dato, controllo, azione. Ogni approfondimento tecnico deve rafforzare almeno uno di questi quattro punti.

Formalizzazione rigorosa

Per rendere dbt fundamentals e project structure analizzabile, definisci prima l’unità di lavoro: source, model, test, mart, metrica o esposizione. Poi collega questa unità a una metrica osservabile: freshness, lineage, test coverage, costo modello e fiducia stakeholder. Infine dichiara la decisione attesa: modello dbt, semantic layer, contratto, test o pipeline di release.

ElementoSpecifica richiesta
Unità di analisisource, model, test, mart, metrica o esposizione
Segnale principalefreshness, lineage, test coverage, costo modello e fiducia stakeholder
BaselinePeriodo precedente, gruppo comparabile, benchmark o scenario controfattuale
Decisionemodello dbt, semantic layer, contratto, test o pipeline di release
RischioScambiare un numero disponibile per una prova sufficiente

La formalizzazione e solida quando un altro analista può riprodurre la logica, criticare le assunzioni e ottenere la stessa decisione partendo dagli stessi dati.

Esempio o caso studio

Un nuovo repository dbt deve integrare Stripe, HubSpot e tracking eventi. La struttura iniziale decide molto: source YAML, staging per ogni sistema, naming coerente, cartelle marts e target dev/prod separati evitano confusione appena arrivano le prime richieste.

Evidenza osservataLettura prudenteAzione consigliata
Il numero miglioraPotrebbe essere effetto reale o variazione normaleCercare confronto e segmento
Un segmento cambia più degli altriLa media aggregata nasconde una differenzaSeparare coorti o casi d’uso
Il costo cresce insieme al risultatoL’impatto va letto sul margineStimare trade-off e sostenibilità

Lab / esercizio

Livello base

Scrivi una scheda di una pagina per dbt fundamentals e project structure: decisione da supportare, metrica primaria, baseline, rischio principale e azione se il segnale e confermato.

Livello intermedio

Costruisci una tabella con tre segmenti, periodi o scenari. Per ciascuno indica cosa cambia, quale spiegazione alternativa e plausibile e quale controllo useresti prima di raccomandare un azione.

Livello research-grade

Prepara un decision memo: ipotesi, dati richiesti, criteri di esclusione, controlli di qualità, soglia decisionale, rischio residuo e piano di monitoraggio dopo la decisione.

Dataset e materiali consigliati

Usa dbt, warehouse, sorgenti CRM, eventi, marts, semantic layer e lineage. Se non hai accesso a dati reali, crea un dataset sintetico con almeno 200 righe, una dimensione temporale, una dimensione segmento e una metrica di outcome.

Errore tipico da evitare

L’errore più comune e usare dbt fundamentals e project structure come etichetta invece che come processo. Succede quando il team mostra un grafico senza decisione, una metrica senza baseline, o una conclusione senza indicare quale assunzione potrebbe invalidarla.

La domanda di controllo è: se questo risultato fosse instabile, quale scelta sbaglierei? Se la risposta non è concreta, manca ancora il collegamento tra analisi e azione.

Quiz o checkpoint

  1. Quale decisione concreta dovrebbe migliorare questa lezione?
  2. Quale unità di analisi rende il problema misurabile?
  3. Quale baseline useresti per evitare una lettura ingenua?
  4. Quale errore tipico potrebbe cambiare la conclusione?
  5. Quale output consegneresti a uno stakeholder non tecnico?

Riepilogo operativo

dbt fundamentals e project structure diventa utile quando produce una decisione più chiara, non quando aggiunge terminologia. Usa il framework problema, modello, formalizzazione, esempio, lab e checkpoint per trasformare la lezione in pratica verificabile. Categoria: Tecnico. Difficoltà: advanced. Tempo stimato: 22 min.

Approfondimento di pratica

Per consolidare dbt fundamentals e project structure, trattala come una piccola prova di lavoro dentro un progetto dbt o semantic layer in cui una metrica deve diventare affidabile per altri team. Non basta dire di aver capito la lezione: devi produrre un modello dati testato, documentato e accompagnato da ownership chiara. Questo passaggio serve a rendere la conoscenza trasferibile, perché obbliga a separare contesto, misura, azione e limite.

Esempio operativo

Parti da una domanda semplice: quale scelta diventerebbe migliore se applicassi bene questa lezione? Nel modulo analytics engineering, la risposta deve sempre collegare un problema reale a un output osservabile. Se stai studiando una lezione di tipo Tecnico, costruisci un esempio con tre righe: il contesto in cui nasce la domanda, il dato o il modello che useresti per leggerla, e la decisione che prenderesti dopo aver controllato i rischi.

Un esempio valido non deve essere grande. Può essere una tabella con una baseline e due segmenti, una query che verifica una definizione, un disegno di esperimento, un controllo su un modello o un memo di dieci righe. La qualità non dipende dalla complessità tecnica, ma dalla tracciabilità del ragionamento: chi legge deve capire perché hai scelto quella metrica, quale alternativa hai scartato e quale evidenza ti farebbe cambiare idea.

Checkpoint di lavoro

  • Scrivi la decisione che questa lezione dovrebbe migliorare, usando un verbo operativo: allocare, fermare, correggere, lanciare, misurare, priorizzare o investigare.
  • Definisci il segnale principale e almeno un guardrail. Il segnale dice dove guardi; il guardrail evita che una scelta localmente buona rovini il sistema.
  • Aggiungi una baseline. Senza baseline non sai se il numero e alto, basso, stabile, anomalo o solo raccontato male.
  • Esplicita il rischio più probabile: trasformare dati instabili in una tabella elegante ma non governabile. Scrivilo prima della raccomandazione, non dopo.
  • Chiudi con un output consegnabile: dashboard, query, schema, memo, esperimento, notebook o checklist. Deve essere qualcosa che un reviewer possa aprire e criticare.

Riepilogo di padronanza

Hai davvero assimilato dbt fundamentals e project structure quando riesci a usarla in tre modi: spiegare il concetto senza gergo inutile, applicarlo a un caso piccolo ma realistico, e difendere una raccomandazione includendo limiti e prossimi controlli. Se manca uno di questi tre elementi, torna al modello concettuale e riduci l’ambizione dell’esempio. Meglio una prova piccola ma rigorosa di un grande progetto che non rende verificabile la decisione.