dbt nel 2026: Trasformazioni Dati, Testing e Domande da Colloquio
Guida completa a dbt nel 2026: modellazione a layer, materializzazioni, testing della qualità dei dati e domande frequenti nei colloqui di data engineering.

dbt (data build tool) si è affermato come lo standard de facto per le trasformazioni dati all'interno del modern data stack. Nel 2026, con il rilascio di dbt Core v1.10 e l'introduzione del Fusion Engine, lo strumento ha raggiunto un livello di maturità che lo rende imprescindibile per qualsiasi data engineer. Dalla modellazione SQL modulare al testing automatizzato della qualità dei dati, dbt consente ai team di trattare le pipeline analitiche con la stessa disciplina ingegneristica applicata al codice applicativo. Questo articolo esplora in profondità le funzionalità chiave di dbt, le best practice per la modellazione dei dati e le domande più frequenti nei colloqui tecnici di data engineering.
Nei colloqui tecnici del 2026, la conoscenza di dbt non è più un valore aggiunto ma un requisito. I recruiter si aspettano che i candidati sappiano spiegare la differenza tra materializzazioni, strutturare un progetto a layer e scrivere test sulla qualità dei dati. Padroneggiare questi concetti rappresenta un vantaggio competitivo significativo.
Modellazione a layer: Staging, Intermediate e Marts
Uno dei principi architetturali fondamentali di dbt è la separazione delle trasformazioni in layer distinti. Questo approccio garantisce leggibilità, manutenibilità e riutilizzabilità del codice SQL. La convenzione più diffusa prevede tre livelli: staging, intermediate e marts.
Il layer di staging rappresenta il punto di ingresso dei dati grezzi nel progetto dbt. I modelli in questo layer si occupano esclusivamente di pulizia, rinominazione delle colonne e casting dei tipi. Non contengono logica di business né join tra tabelle diverse.
-- models/staging/stg_orders.sql
WITH source AS (
SELECT * FROM {{ source('ecommerce', 'raw_orders') }}
)
SELECT
id AS order_id,
customer_id,
CAST(order_date AS DATE) AS order_date,
CAST(amount AS DECIMAL(10, 2)) AS order_amount,
LOWER(status) AS order_status
FROM source
WHERE id IS NOT NULLIl layer intermediate ospita le trasformazioni che combinano più modelli di staging. Qui si eseguono join, aggregazioni e calcoli che servono come base per i modelli finali. Questi modelli non vengono esposti direttamente agli utenti di business.
-- models/intermediate/int_customer_orders.sql
WITH orders AS (
SELECT * FROM {{ ref('stg_orders') }}
),
customers AS (
SELECT * FROM {{ ref('stg_customers') }}
)
SELECT
c.customer_id,
c.customer_name,
COUNT(o.order_id) AS total_orders,
SUM(o.order_amount) AS lifetime_value,
MIN(o.order_date) AS first_order_date,
MAX(o.order_date) AS last_order_date
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.customer_nameInfine, il layer marts contiene i modelli pronti per il consumo da parte degli analisti e delle dashboard. Ogni mart è ottimizzato per un caso d'uso specifico e rappresenta la "verità" per un determinato dominio di business.
-- models/marts/fct_daily_revenue.sql
{{
config(
materialized='incremental',
unique_key='revenue_date',
incremental_strategy='merge'
)
}}
SELECT
DATE(order_date) AS revenue_date,
SUM(order_amount) AS daily_revenue,
COUNT(DISTINCT customer_id) AS unique_customers
FROM {{ ref('stg_orders') }}
WHERE order_status = 'completed'
{% if is_incremental() %}
AND order_date > (SELECT MAX(revenue_date) FROM {{ this }})
{% endif %}
GROUP BY DATE(order_date)Questa struttura a tre livelli non è solo una convenzione stilistica: consente di isolare le modifiche, facilitare il debugging e garantire che ogni trasformazione abbia una responsabilità chiara e ben definita.
La funzione ref() e il DAG
La funzione ref() è il meccanismo centrale attraverso cui dbt costruisce il DAG (Directed Acyclic Graph) delle dipendenze tra modelli. Ogni volta che un modello utilizza ref('nome_modello'), dbt registra automaticamente la relazione di dipendenza e garantisce che i modelli vengano eseguiti nell'ordine corretto.
-- Bad: hardcoded reference, no dependency tracking
SELECT * FROM analytics.stg_orders
-- Good: ref() registers the dependency
SELECT * FROM {{ ref('stg_orders') }}L'utilizzo di ref() offre diversi vantaggi concreti. In primo luogo, il DAG permette a dbt di parallelizzare l'esecuzione dei modelli indipendenti, riducendo significativamente i tempi di build. In secondo luogo, rende il progetto portabile tra ambienti diversi (sviluppo, staging, produzione) senza modificare alcuna query. Infine, il DAG fornisce una mappa visuale dell'intero flusso dei dati, strumento indispensabile per il debugging e la documentazione.
Durante un colloquio, è fondamentale saper spiegare che ref() non è un semplice alias per il nome di una tabella: è il mattone su cui si costruisce l'intera orchestrazione delle trasformazioni.
Materializzazioni: view, table, incremental ed ephemeral
Le materializzazioni determinano il modo in cui dbt persiste i risultati di un modello nel data warehouse. La scelta della materializzazione corretta ha un impatto diretto sulle performance e sui costi di elaborazione.
Una view è la materializzazione predefinita. Non persiste dati: ogni volta che viene interrogata, il warehouse riesegue la query sottostante. Si adatta bene ai modelli di staging leggeri. Una table materializza il risultato come tabella fisica, ricreandola completamente ad ogni esecuzione. Garantisce performance di lettura ottimali ma richiede un full refresh ogni volta.
La materializzazione incremental è la più sofisticata. Elabora solo le righe nuove o modificate rispetto all'ultima esecuzione, riducendo drasticamente tempi e costi per tabelle di grandi dimensioni. Come si osserva nel modello fct_daily_revenue presentato sopra, il blocco is_incremental() filtra i dati già elaborati. La strategia merge consente inoltre di aggiornare righe esistenti quando la chiave univoca corrisponde.
Infine, i modelli ephemeral non vengono mai materializzati nel warehouse. Vengono interpolati come CTE (Common Table Expression) all'interno dei modelli che li referenziano. Sono utili per logiche intermedie molto semplici che non meritano una tabella o view dedicata.
Pronto a superare i tuoi colloqui su Data Engineering?
Pratica con i nostri simulatori interattivi, flashcards e test tecnici.
Testing della qualità dei dati
Uno degli aspetti che differenzia dbt da un semplice esecutore di SQL è il framework di testing integrato. dbt supporta due categorie principali di test: i generic test dichiarativi e i singular test personalizzati.
I generic test vengono definiti nei file YAML di schema e coprono i controlli più comuni: unicità, valori non nulli, integrità referenziale e valori ammessi.
# models/staging/_stg_models.yml
version: 2
models:
- name: stg_orders
columns:
- name: order_id
tests:
- unique
- not_null
- name: order_status
tests:
- accepted_values:
values: ['completed', 'pending', 'cancelled', 'refunded']
- name: customer_id
tests:
- not_null
- relationships:
to: ref('stg_customers')
field: customer_idQuesta configurazione dichiara che order_id deve essere unico e non nullo, che order_status può assumere solo quattro valori specifici e che ogni customer_id deve corrispondere a un record nella tabella stg_customers. Un singolo dbt test esegue tutte queste validazioni e segnala eventuali violazioni.
I singular test, invece, sono query SQL personalizzate salvate nella directory tests/. Un test passa se la query restituisce zero righe, e fallisce in caso contrario.
-- tests/assert_revenue_never_negative.sql
SELECT
revenue_date,
daily_revenue
FROM {{ ref('fct_daily_revenue') }}
WHERE daily_revenue < 0Questo test verifica che il fatturato giornaliero non sia mai negativo, una condizione che potrebbe indicare un errore nei dati di origine o nella logica di trasformazione. Integrare questi test in una pipeline CI/CD garantisce che ogni modifica al codice venga validata automaticamente prima del deploy in produzione.
dbt Core v1.10 e il Fusion Engine
Il 2026 ha portato novità significative nell'ecosistema dbt. La versione 1.10 di dbt Core introduce il Fusion Engine, un motore di esecuzione riprogettato da zero che rappresenta il cambiamento architetturale più importante dalla nascita del progetto.
Il Fusion Engine unifica la compilazione e l'esecuzione dei modelli in un unico processo ottimizzato. Il risultato è una riduzione dei tempi di build che, secondo i benchmark ufficiali, può raggiungere il 40-60% su progetti di medie e grandi dimensioni. Il motore sfrutta un sistema avanzato di caching dei metadati e parallelismo adattivo che distribuisce il carico in base alle risorse disponibili.
Tra le altre novità di rilievo si segnalano il supporto nativo per le unit test sui modelli, che consentono di testare la logica di trasformazione con dati di input sintetici senza necessità di eseguire query sul warehouse. Questa funzionalità permette cicli di sviluppo più rapidi e riduce i costi di computazione durante le fasi di test.
Dal punto di vista della governance, dbt Core v1.10 integra il column-level lineage direttamente nella documentazione generata, offrendo una tracciabilità granulare che mostra esattamente come ogni colonna viene derivata attraverso i vari layer di trasformazione.
Macro e Jinja: codice SQL riutilizzabile
Le macro di dbt sfruttano il motore di template Jinja per introdurre logica programmabile all'interno dell'SQL. Una macro è essenzialmente una funzione riutilizzabile che genera codice SQL dinamicamente.
-- macros/cents_to_dollars.sql
{% macro cents_to_dollars(column_name) %}
ROUND({{ column_name }} / 100.0, 2)
{% endmacro %}Questa macro converte un importo da centesimi a dollari con due decimali. Una volta definita, può essere invocata in qualsiasi modello con la sintassi {{ cents_to_dollars('amount_cents') }}, eliminando duplicazioni e garantendo coerenza nelle trasformazioni.
Le macro trovano applicazione in numerosi scenari: conversioni di valuta, generazione di surrogate key, implementazione di pattern di Slowly Changing Dimension (SCD), filtri temporali standardizzati e molto altro. I package della community, distribuiti tramite il dbt Hub, offrono centinaia di macro pronte all'uso, dal package dbt_utils per le utilità generiche a dbt_expectations per test avanzati ispirati a Great Expectations.
Nei colloqui tecnici, viene spesso chiesto di descrivere un caso d'uso reale per le macro. La risposta migliore è presentare un esempio concreto che dimostri come una macro riduca la duplicazione del codice e standardizzi una logica di business applicata in più modelli.
Domande frequenti nei colloqui su dbt
Di seguito sono raccolte le domande più comuni poste durante i colloqui tecnici di data engineering relativamente a dbt, con risposte sintetiche ma complete.
Qual è la differenza tra source() e ref()?
source() fa riferimento a tabelle raw che esistono già nel data warehouse e non sono gestite da dbt. ref() fa riferimento a modelli definiti all'interno del progetto dbt. Entrambe le funzioni registrano dipendenze nel DAG, ma source() consente anche di definire freshness test per monitorare la latenza dei dati di origine.
Quando utilizzare una materializzazione incremental rispetto a una table?
La materializzazione incremental è la scelta giusta quando la tabella di destinazione è molto grande e i nuovi dati si aggiungono in modo prevedibile (ad esempio, eventi con timestamp). La materializzazione table è più appropriata quando i dati vengono aggiornati in modo imprevedibile o quando la tabella è sufficientemente piccola da poter essere ricreata completamente ad ogni run senza impatto significativo su tempi e costi.
Come si gestiscono i late-arriving data in un modello incremental?
Si utilizzano strategie come il lookback window, che estende la finestra temporale di elaborazione per catturare dati arrivati in ritardo. In alternativa, si può configurare un full_refresh periodico (ad esempio settimanale) per riallineare l'intera tabella, oppure utilizzare la strategia merge con una chiave univoca che consente l'aggiornamento di righe già esistenti.
Che ruolo svolgono le macro in un progetto dbt?
Le macro consentono di scrivere logica SQL riutilizzabile tramite il template engine Jinja. Eliminano la duplicazione del codice, standardizzano le trasformazioni e permettono di implementare pattern complessi in modo centralizzato. Possono essere distribuite come package e condivise tra progetti diversi.
Come si integra dbt in una pipeline CI/CD?
L'integrazione tipica prevede l'esecuzione di dbt build (che comprende run e test) in un ambiente di staging ad ogni pull request. Se tutti i modelli vengono compilati correttamente e i test passano, la modifica viene approvata per il merge. In produzione, un job schedulato esegue dbt build con cadenza regolare. Strumenti come GitHub Actions, GitLab CI o dbt Cloud orchestrano questo flusso.
Che cos'è il Fusion Engine introdotto in dbt Core v1.10?
Il Fusion Engine è il nuovo motore di esecuzione di dbt che unifica compilazione ed esecuzione in un processo ottimizzato. Sfrutta caching dei metadati e parallelismo adattivo per ridurre i tempi di build del 40-60%. Rappresenta la riscrittura architetturale più significativa nella storia di dbt Core.
Inizia a praticare!
Metti alla prova le tue conoscenze con i nostri simulatori di colloquio e test tecnici.
Conclusione
dbt ha trasformato radicalmente il modo in cui i team di data engineering affrontano le trasformazioni analitiche, introducendo pratiche di ingegneria del software in un dominio tradizionalmente dominato da script SQL monolitici. Nel 2026, la padronanza di questo strumento è un requisito fondamentale per chi opera nel campo del data engineering.
I punti chiave da ricordare per un colloquio tecnico su dbt sono:
- Architettura a layer: staging per la pulizia dei dati grezzi, intermediate per le trasformazioni complesse, marts per i modelli pronti al consumo
- ref() e il DAG: il meccanismo che garantisce ordine di esecuzione, portabilità tra ambienti e parallelizzazione automatica
- Materializzazioni: la scelta tra view, table, incremental ed ephemeral dipende dal volume dei dati, dalla frequenza di aggiornamento e dai requisiti di performance
- Testing integrato: generic test dichiarativi e singular test personalizzati proteggono la qualità dei dati ad ogni esecuzione
- Fusion Engine: il nuovo motore di dbt Core v1.10 riduce significativamente i tempi di build attraverso caching e parallelismo adattivo
- Macro e Jinja: consentono di scrivere SQL riutilizzabile, standardizzare le trasformazioni e condividere logica tra progetti
Investire tempo nello studio approfondito di dbt non significa solo prepararsi per un colloquio: significa acquisire competenze che rendono più efficiente, affidabile e governabile l'intero ciclo di vita dei dati all'interno di un'organizzazione.
Tag
Condividi
Articoli correlati

Le 25 domande piu frequenti nei colloqui di Data Engineering nel 2026
Le 25 domande piu frequenti nei colloqui di data engineering nel 2026: SQL, data pipeline, ETL/ELT, Spark, Kafka, data modeling e system design con risposte dettagliate.

Apache Spark 4 nel 2026: Nuove Funzionalita, Structured Streaming e Domande da Colloquio
Guida completa ad Apache Spark 4 con le novita principali: modalita ANSI SQL, tipo VARIANT, Real-Time Mode, Spark Connect e Declarative Pipelines. Include domande da colloquio di data engineering con risposte dettagliate.

ETL vs ELT nel 2026: Architettura delle Data Pipeline a confronto
Confronto ETL vs ELT per le data pipeline moderne. Differenze architetturali, compromessi su prestazioni e costi, e quando utilizzare ciascun approccio con Snowflake, BigQuery e dbt nel 2026.