전체 그래프
dbt

Macros & Jinja

data-engineeringdbtmacrojinja

상위: dbt

요약

dbt는 Jinja 템플릿 엔진을 사용하여 SQL에 프로그래밍 기능을 추가한다. 변수, 조건문, 반복문, 매크로(재사용 함수)를 활용하여 반복적인 SQL 패턴을 DRY(Don't Repeat Yourself)하게 관리할 수 있다.

Jinja 기본 문법

표현식

-- {{ ... }}  값을 출력
SELECT * FROM {{ ref('stg_orders') }}

구문

-- {% ... %}  제어문 (출력 없음)
{% set payment_methods = ['credit_card', 'bank_transfer', 'coupon'] %}

주석

-- {# ... #}  Jinja 주석 (컴파일 결과에 포함  )
{#  주석은 컴파일된 SQL에 나타나지 않는다 #}

조건문과 반복문

if / else

SELECT
    order_id,
    {% if target.name == 'prod' %}
        user_id,
        email
    {% else %}
        'masked' AS user_id,
        'masked' AS email
    {% endif %}
FROM {{ ref('stg_orders') }}

target.name으로 환경(dev/prod)을 분기할 수 있다.

for 반복문

{% set payment_methods = ['credit_card', 'bank_transfer', 'coupon'] %}

SELECT
    order_id,
    {% for method in payment_methods %}
        SUM(CASE WHEN payment_method = '{{ method }}' THEN amount END)
            AS {{ method }}_amount
        {% if not loop.last %},{% endif %}
    {% endfor %}
FROM {{ ref('stg_payments') }}
GROUP BY order_id

반복적인 CASE WHEN 패턴을 자동 생성한다. loop.last로 마지막 반복에서 쉼표를 제거한다.

Macros (매크로)

매크로는 재사용 가능한 Jinja 함수이다.

정의

-- macros/cents_to_dollars.sql
{% macro cents_to_dollars(column_name, precision=2) %}
    ROUND({{ column_name }} / 100, {{ precision }})
{% endmacro %}

사용

SELECT
    order_id,
    {{ cents_to_dollars('amount_cents') }} AS amount_dollars
FROM {{ ref('stg_payments') }}

컴파일 결과

SELECT
    order_id,
    ROUND(amount_cents / 100, 2) AS amount_dollars
FROM analytics.stg_payments

실용적 매크로 패턴

날짜 트렁케이트 (웨어하우스 간 호환)

{% macro date_trunc(datepart, date) %}
    {% if target.type == 'bigquery' %}
        DATE_TRUNC({{ date }}, {{ datepart }})
    {% elif target.type == 'snowflake' %}
        DATE_TRUNC('{{ datepart }}', {{ date }})
    {% endif %}
{% endmacro %}

감사 컬럼 자동 추가

{% macro audit_columns() %}
    CURRENT_TIMESTAMP() AS _loaded_at,
    '{{ invocation_id }}' AS _dbt_run_id
{% endmacro %}
SELECT
    order_id,
    amount,
    {{ audit_columns() }}
FROM {{ source('jaffle_shop', 'orders') }}

Hooks (pre-hook / post-hook)

모델 빌드 전후에 SQL을 실행할 수 있다.

{{ config(
    materialized='table',
    pre_hook="GRANT SELECT ON {{ this }} TO ROLE analyst",
    post_hook="ALTER TABLE {{ this }} SET DATA_RETENTION_TIME_IN_DAYS = 7"
) }}

SELECT ...
  • pre-hook: 모델 빌드 에 실행
  • post-hook: 모델 빌드 에 실행
  • 권한 부여, 인덱스 생성, 데이터 보관 정책 등에 활용

패키지 (dbt Packages)

외부에서 만든 매크로 모음을 설치하여 사용할 수 있다.

# packages.yml
packages:
  - package: dbt-labs/dbt_utils
    version: 1.3.0
  - package: dbt-labs/codegen
    version: 0.12.0
dbt deps    # 패키지 설치

주요 패키지:

  • dbt-utils: 범용 매크로 (surrogate_key, date_spine 등)
  • codegen: YAML/SQL 코드 자동 생성
  • dbt-expectations: Great Expectations 스타일 테스트

관련 개념

  • Models: 매크로와 Jinja를 사용하는 주체
  • Tests: 커스텀 Generic 테스트도 매크로로 정의한다