Configurare de bază dbt: Structura proiectului, Profiluri de conexiune și Prima transformare SQL
De la linia de comandă la prima transformare: Configurați dbt Core cu profiles.yml pentru BigQuery, Snowflake sau PostgreSQL, explorați structura proiectului (modele, teste, semințe, macrocomenzi) și descoperiți macro-ul ref() care creează dependențe automate între modele.
Cerințe preliminare și instalare
dbt Core necesită Python 3.8+ și se instalează prin pip. Important este să instalați nu numai pachetul de bază, ci șiadaptor specific pentru depozitul dvs. Fiecare depozit are propriul adaptor, deoarece dialectele SQL diferă.
# 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!
Începeți cu DuckDB pentru dezvoltare locală
Dacă nu aveți acces imediat la BigQuery sau Snowflake, DuckDB este calea mai rapid de început: este o bază de date încorporată care rulează direct local, nu necesită infrastructură și dbt-duckdb funcționează pe orice mașină. Perfect pentru invatare fara costuri.
Creați primul proiect dbt
Comanda dbt init creează structura de foldere a unui proiect dbt și vă ghidează
în configurația inițială:
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
Fișierul dbt_project.yml
Inima configurației proiectului este dbt_project.yml. Definiți aici
numele proiectului, versiunea dbt, căile de director și configurația globală
dintre modele:
# 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
Fișierul profiles.yml
Acreditările de conectare intră ~/.dbt/profiles.yml (în directorul principal,
nu în depozit). Fiecare profil poate avea mai multe ținte (dezvoltare, montaj, producție):
# ~/.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
Convenția este că fiecare dezvoltator are un model personal (de ex. dbt_dev_federico)
pentru a evita conflictele în timpul dezvoltării paralele.
Modele dbt: Unitatea fundamentală
Un model dbt este un fișier .sql în director models/. Conținutul
este un simplu SELECT — dbt se ocupă de crearea vizualizării sau a tabelului corespunzător în depozit.
Să începem cu un exemplu realist. Să presupunem că avem o masă raw.orders in
depozit cu date brute din aplicație:
-- 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
Macro-ul ref().
Macro-ul ref() este cea mai importantă caracteristică a dbt. Când scrii
{{ ref('stg_orders') }}, dbt:
- Rezolvă numele corect al tabelului/vizualizării din depozit pentru mediul curent
- Înregistrați dependența în graficul aciclic direcționat (DAG)
- Se asigură că modelul dependent rulează primul
-- 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
Macro-ul sursă ().
Pentru a accesa surse brute (tabele care nu sunt create de dbt), utilizați source() în loc de
ref(). Sursele trebuie declarate într-un dosar 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"
Cu această configurare, puteți rula dbt source freshness pentru a verifica asta
sursele sunt actualizate înainte de începerea transformărilor.
Rulați dbt: comenzile de bază
# 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
Structura șablonului recomandată
Structura pe trei niveluri recomandată de comunitatea 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: logica de afaceri în punere în scenă
Șabloanele de punere în scenă trebuie să facă doar operațiuni „prostie”: redenumiți coloanele, tipurile de difuzare, deduplicat. Logica de business (calcule, agregari, uniuni) intra in modelele intermediare sau magazine. Dacă modelul dvs. de pregătire are un GROUP BY sau mai mult de câteva coloane calculate, probabil că faci prea multe în acel strat.
Verificarea setării cu dbt debug
Înainte de a alerga dbt run, verificați dacă conexiunea depozitului funcționează:
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]
Concluzii și pașii următori
Am configurat un proiect dbt funcțional cu structura pe trei niveluri (staging →
intermediar → mart), profilele de conectare pentru diferite medii, sursele declarate
cu verificarea prospetimei si primele modele cu ref() e source().
Următorul pas este să facem SQL-ul nostru dinamic cu Jinja: variabile, bucle, condiții și macrocomenzi reutilizabile care elimină duplicarea codului în depozit.







