dbt 실무 스터디 가이드

데이터 엔지니어 · AI 엔지니어를 위한 핵심 요약

Transformation ELT SQL Data Pipeline 버전 관리 최신 업데이트: 2026.03

📚 목차

  1. dbt란?
  2. 왜 써야 하는가? (기존 대안과 비교)
  3. 핵심 개념
  4. 퀵스타트: 설치부터 첫 모델까지
  5. 핵심 설정 레퍼런스
  6. 실무 팁 & 트러블슈팅
  7. 참고 자료

1. dbt란?

dbt(Data Build Tool)는 데이터 웨어하우스 내에서 변환(Transformation) 작업을 버전 관리, 테스트, 문서화할 수 있게 해주는 개발 도구입니다. "ELT의 T"에 집중하며, 분석가와 엔지니어가 SQL 중심으로 데이터 파이프라인을 구축하고 운영할 수 있는 프레임워크를 제공합니다.

📝 SQL 중심 개발

Python이나 Java가 아닌 SQL로 비즈니스 로직을 정의합니다. Jinja2 템플릿을 통해 반복문, 조건문, 매크로를 사용해 동적 SQL을 작성할 수 있습니다.

🔄 버전 관리 & 협업

모든 모델(SQL 파일)과 설정이 코드로 관리되므로 Git을 통한 버전 관리, 코드 리뷰, CI/CD 파이프라인 적용이 자연스럽습니다.

✅ 테스트 & 문서화 자동화

선언적 테스트(not null, unique 등)와 사용자 정의 테스트를 쉽게 추가할 수 있으며, `dbt docs generate`로 데이터 계보(Lineage)와 문서를 자동 생성합니다.

핵심 포인트

dbt는 실행 엔진이 아닌, 변환 로직을 정의하고 관리하는 도구입니다. 실제 쿼리는 Snowflake, BigQuery, Redshift 등의 데이터 웨어하우스에서 실행됩니다.

2. 왜 써야 하는가? (기존 대안과 비교)

기존의 데이터 변환 방식(스케줄러 + SQL 스크립트, Spark/Airflow Python 작업)과 dbt를 비교합니다.

방식 장점 단점 dbt의 해결책
스케줄러 + SQL 파일
(Crontab, Airflow SQLOperator)
간단한 설정, SQL만 알면 됨 의존성 관리 어려움, 테스트/문서화 부재, 코드 중복 DAG 기반 의존성 자동 추론, 내장 테스트 프레임워크, Jinja 매크로로 재사용
Spark/PySpark
(Airflow, Databricks)
대규모 데이터 처리, 복잡한 비즈니스 로직 가능 운영 복잡도 높음, SQL 분석가 참여 어려움, 클러스터 비용 SQL 중심으로 분석가와 협업 용이, 웨어하우스 컴퓨팅만 사용
프로프라이etary ETL
(Informatica, Talend)
GUI 기반 개발, 통합 관리 비용 높음, 벤더 락인, 버전 관리 어려움 오픈소스, 코드 기반(Git), 클라우드 웨어하우스 네이티브

⚠️ dbt가 적합하지 않은 경우

실시간 스트리밍 처리, 데이터 웨어하우스 외부의 데이터 소스 변환, 매우 복잡한 비정형 데이터 처리에는 다른 도구(Spark, Flink)를 고려해야 합니다.

3. 핵심 개념

dbt 프로젝트의 기본 구조와 주요 컴포넌트를 이해합니다.

프로젝트 구조

my_dbt_project/
├── dbt_project.yml          # 프로젝트 설정의 핵심
├── models/                  # 분석 모델 (SQL + YAML)
│   ├── staging/             # 스테이징 레이어
│   ├── marts/               # 데이터 마트 (BI용)
│   └── schema.yml           # 모델 정의, 테스트, 문서화
├── macros/                  # 재사용 가능한 Jinja 매크로
├── tests/                   # 사용자 정의 테스트 (SQL/Python)
├── snapshots/               # SCD Type2 스냅샷
└── seeds/                   # 정적 CSV 데이터
        

아키텍처 다이어그램

[소스 시스템] [데이터 웨어하우스] [dbt 실행] ┌─────────┐ ┌─────────────────┐ ┌─────────────────┐ │ DB │─────▶│ RAW │────▶│ dbt run │ │ API │─┐ │ (Bronze) │ │ │ │ CSV │ └───▶│ 테이블 │ │ 1. 모델 의존성 │ └─────────┘ └─────────────────┘ │ 분석(DAG) │ │ 2. SQL 컴파일 │ [BI/분석 도구] │ (Jinja → SQL) │ ┌─────────┐ ┌─────────────────┐ │ 3. 실행 │ │ Looker │◀─────│ TRANSFORMED │◀────┼─────────────────┘ │ Tableau │ │ (Silver/Gold) │ │ │ Metabase│ │ 데이터 마트 │ │ dbt test └─────────┘ └─────────────────┘ │ - 유니크 │ - Not Null [문서/계보] │ - 관계성 ┌─────────┐ └─────────────────┘ │ dbt docs │◀───────────────────────────────────┘ │ 사이트 │ └─────────┘

주요 컴포넌트

4. 퀵스타트: 설치부터 첫 모델까지

1 설치 및 프로젝트 생성

Python 환경에서 dbt-core와 데이터 웨어하우스 어댑터를 설치합니다. (예: Snowflake)

CLI
pip install dbt-core dbt-snowflake
# 프로젝트 생성 (현재 디렉토리에 생성)
dbt init my_analytics_project

2 프로필 설정 (~/.dbt/profiles.yml)

데이터 웨어하우스 연결 정보를 설정합니다.

~/.dbt/profiles.yml
my_analytics_project:
  target: dev
  outputs:
    dev:
      type: snowflake
      account: your_account
      user: your_user
      password: "{{ env_var('DBT_PASSWORD') }}"
      role: transformer
      database: analytics
      warehouse: transform_wh
      schema: dbt_dev
      threads: 4

3 첫 번째 모델 생성

models/staging/jaffle_shop/orders.sql 파일을 생성합니다.

models/staging/jaffle_shop/orders.sql
{{ config(materialized='view') }}

with orders as (
    select * from {{ source('jaffle_shop', 'orders') }}
),

final as (
    select
        id as order_id,
        user_id as customer_id,
        order_date,
        status,
        -- 매크로 사용 예시
        {{ cents_to_dollars('amount') }} as amount_usd
    from orders
    where order_date >= '2024-01-01'
)

select * from final

4 모델 정의 및 테스트 설정

models/staging/jaffle_shop/schema.yml 파일을 생성합니다.

models/staging/jaffle_shop/schema.yml
version: 2

sources:
  - name: jaffle_shop
    database: raw
    schema: jaffle_shop
    tables:
      - name: orders
        loaded_at_field: _loaded_at
        freshness:
          warn_after: {count: 12, period: hour}
          error_after: {count: 24, period: hour}

models:
  - name: orders
    description: "Cleaned and transformed orders table."
    columns:
      - name: order_id
        description: "Primary key for orders."
        tests:
          - unique
          - not_null
      - name: customer_id
        tests:
          - relationships:
              to: ref('customers')
              field: customer_id
      - name: status
        tests:
          - accepted_values:
              values: ['placed', 'shipped', 'completed', 'returned']

5 실행 및 테스트

CLI
# 모델 실행 (DAG 기반)
dbt run --select orders

# 특정 태그가 있는 모델만 실행
dbt run --select tag:staging

# 테스트 실행
dbt test --models orders

# 문서 생성 및 서버 실행
dbt docs generate
dbt docs serve --port 8080

5. 핵심 설정 레퍼런스

dbt_project.yml 파일의 주요 설정값들입니다.

설정 기본값 설명 실무 예시
name - 프로젝트 이름 name: my_analytics
version 1.0.0 프로젝트 버전 (SemVer) version: '1.2.0'
profile - 프로필 이름 (profiles.yml과 매핑) profile: my_analytics_project
model-paths ["models"] 모델 파일 경로 model-paths: ["models", "transformations"]
seed-paths ["seeds"] 시드 파일 경로 seed-paths: ["seeds", "static_data"]
test-paths ["tests"] 테스트 파일 경로 test-paths: ["tests", "custom_tests"]
models {} 모델별 설정 (머티리얼라이제이션, 태그 등)
models:
  my_analytics:
    staging:
      materialized: view
      tags: ["staging"]
    marts:
      materialized: table
      tags: ["marts"]
seeds {} 시드 설정 (컬럼 타입 등)
seeds:
  my_analytics:
    country_codes:
      column_types:
        country_code: varchar(2)
        country_name: varchar(100)
vars {} 전역 변수 (Jinja에서 사용)
vars:
  start_date: '2024-01-01'
  currency: 'USD'
query-comment null 실행 쿼리에 추가할 주석 query-comment: "{{ node.name }}"

6. 실무 팁 & 트러블슈팅

자주 겪는 문제와 해결책

🔍 문제: 모델 실행 순서가 예상과 다름

원인: dbt는 ref() 함수를 통해 의존성을 자동 추론합니다. 명시적 의존성이 없으면 실행 순서가 보장되지 않습니다.

해결: dbt compile 후 target/compiled 디렉토리에서 생성된 SQL을 확인하세요. dbt ls --resource-type model --output name,depends_on으로 의존성 그래프를 확인합니다.

⚠️ 문제: 실행 속도가 너무 느림

원인: 너무 많은 모델을 한 번에 실행, 웨어하우스 리소스 부족, 비효율적인 SQL.

해결:

🔍 문제: Jinja 컴파일 에러 (Parsing Error)

원인: Jinja 구문 오류, 중괄호 불일치, 정의되지 않은 변수/매크로 참조.

해결: dbt compile로 컴파일 단계에서 에러를 먼저 확인합니다. 에러 메시지는 정확한 라인을 가리킵니다. {{ debug() }} 매크로로 변수 값을 출력해 디버깅합니다.

🚨 문제: 프로덕션 데이터 손실 위험

원인: dbt run이 기존 테이블을 드롭하고 재생성할 때 예기치 않은 오류 발생.

해결:

성능 최적화 팁

7. 참고 자료

학습 경로 추천

1. 공식 튜토리얼로 기본 개념 익히기 → 2. Jaffle Shop 클론하여 실습 → 3. 실제 데이터로 작은 프로젝트 시작(스테이징 레이어만) → 4. 매크로, 패키지 등 고급 기능 도입 → 5. CI/CD(예: GitHub Actions), 프로덕션 배포 전략 수립