전제조건 및 설치

dbt Core에는 Python 3.8 이상이 필요하며 pip를 통해 설치됩니다. 중요한 것은 설치하는 것입니다. 기본 패키지 뿐만 아니라특정 어댑터 당신의 창고를 위해. SQL 언어가 다르기 때문에 각 웨어하우스에는 자체 어댑터가 있습니다.

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

로컬 개발을 위해 DuckDB 시작하기

BigQuery 또는 Snowflake에 즉시 액세스할 수 없는 경우 덕DB 그게 방법이야 더 빠르게 시작할 수 있습니다. 로컬에서 직접 실행되는 내장형 데이터베이스입니다. 인프라가 필요하지 않으며 dbt-duckdb는 모든 시스템에서 작동합니다. 학습에 적합 비용없이.

첫 번째 dbt 프로젝트 생성

명령 dbt init dbt 프로젝트의 폴더 구조를 생성하고 안내합니다. 초기 구성에서:

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

dbt_project.yml 파일

프로젝트 구성의 핵심은 dbt_project.yml. 여기를 정의하세요 프로젝트 이름, DBT 버전, 디렉터리 경로 및 전역 구성 모델 중:

# 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

프로필.yml 파일

연결 자격 증명이 들어갑니다. ~/.dbt/profiles.yml (홈 디렉토리에서 절대 저장소에 있음). 각 프로필에는 여러 대상(개발, 준비, 프로덕션)이 있을 수 있습니다.

# ~/.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

관례는 각 개발자가 개인적인 패턴(예: dbt_dev_federico) 병렬 개발 중 충돌을 피하기 위해.

dbt 모델: 기본 단위

DBT 모델은 파일입니다 .sql 디렉토리에 models/. 내용 이는 단순한 SELECT입니다. dbt는 웨어하우스에 해당 뷰나 테이블을 생성하는 작업을 담당합니다.

현실적인 예부터 시작해 보겠습니다. 테이블이 있다고 가정하자 raw.orders 안으로 애플리케이션의 원시 데이터가 있는 창고:

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

ref() 매크로

매크로 ref() dbt의 가장 중요한 기능입니다. 당신이 쓸 때 {{ ref('stg_orders') }}, DBT:

  1. 현재 환경에 대한 웨어하우스의 테이블/뷰의 올바른 이름을 확인합니다.
  2. 방향성 비순환 그래프(DAG)에 종속성을 기록합니다.
  3. 종속 모델이 먼저 실행되도록 보장
-- 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

소스() 매크로

원시 소스(dbt로 생성되지 않은 테이블)에 액세스하려면 다음을 사용하십시오. source() 대신에 ref(). 소스는 파일로 선언해야 합니다. 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"

이 설정을 사용하면 다음을 실행할 수 있습니다. dbt source freshness 그것을 확인하기 위해 변환을 시작하기 전에 소스가 업데이트됩니다.

dbt 실행: 기본 명령

# 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

권장 템플릿 구조

dbt 커뮤니티에서 권장하는 3계층 구조:

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

안티 패턴: 스테이징의 비즈니스 논리

스테이징 템플릿은 "멍청한" 작업(열 이름 바꾸기, 유형 변환, 중복을 제거합니다. 비즈니스 논리(계산, 집계, 조인)는 중간 모델로 들어갑니다. 아니면 마트. 스테이징 모델에 GROUP BY 또는 두 개 이상의 계산된 열이 있는 경우 아마도 해당 레이어에서 너무 많은 일을 하고 있는 것 같습니다.

dbt 디버그로 설정 확인

달리기 전 dbt run, 창고 연결이 작동하는지 확인하십시오.

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]

결론 및 다음 단계

우리는 3단계 구조(스테이징 → 중개 → 마트), 다양한 환경에 대한 연결 프로필, 선언된 소스 신선도 확인 기능을 갖춘 최초의 모델 ref() e source().

다음 단계는 변수, 루프, 조건 등 Jinja를 사용하여 SQL을 동적으로 만드는 것입니다. 창고에서 코드 중복을 제거하는 재사용 가능한 매크로.