dbt fundamentals e project structure
dbt fundamentals e project structure. Lezione su come configurare e strutturare un progetto dbt.
Cosa imparerai
- Comprendere il problema analitico e il contesto decisionale
- Applicare esempi, metriche e controlli a casi reali
Collegamenti
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
| Fase | Cosa chiarire | Output |
|---|---|---|
| Domanda | Quale scelta reale deve migliorare? | Decisione da prendere |
| Misura | Quale segnale osservabile rappresenta il problema? | Metrica o dato sorgente |
| Controllo | Quale baseline rende il risultato interpretabile? | Confronto credibile |
| Azione | Che 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.
| Elemento | Specifica richiesta |
|---|---|
| Unità di analisi | source, model, test, mart, metrica o esposizione |
| Segnale principale | freshness, lineage, test coverage, costo modello e fiducia stakeholder |
| Baseline | Periodo precedente, gruppo comparabile, benchmark o scenario controfattuale |
| Decisione | modello dbt, semantic layer, contratto, test o pipeline di release |
| Rischio | Scambiare 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 osservata | Lettura prudente | Azione consigliata |
|---|---|---|
| Il numero migliora | Potrebbe essere effetto reale o variazione normale | Cercare confronto e segmento |
| Un segmento cambia più degli altri | La media aggregata nasconde una differenza | Separare coorti o casi d’uso |
| Il costo cresce insieme al risultato | L’impatto va letto sul margine | Stimare 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
- Quale decisione concreta dovrebbe migliorare questa lezione?
- Quale unità di analisi rende il problema misurabile?
- Quale baseline useresti per evitare una lettura ingenua?
- Quale errore tipico potrebbe cambiare la conclusione?
- 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.
Percorso collegato
Lezioni da leggere insieme
Questi collegamenti portano la lezione dentro il resto del corso: basi da riprendere, passaggi successivi e connessioni tematiche tra moduli.