2 분 소요

[Airflow]Airflow에서 Jinja 템플릿과 날짜 개념 톺아보기

Airflow에서 Jinja 템플릿과 날짜 개념 정리

1. 시작하며

Airflow를 쓰다 보면 흔히 마주치는 {{ execution_date }}{{ ds }} 같은 템플릿 표현들.

처음엔 단순히 “그날 날짜”겠거니 하고 넘어가지만, 백필(backfill)이나 스케줄을 조금만 복잡하게 구성해보면 “대체 execution_date가 왜 이 시간이지?” “왜 하루 뒤에 실행되지?” 등등 의문이 생기기 시작함.

이번 포스팅에서는 아래 내용을 중심으로 정리해봄:

  • Airflow에서 사용하는 날짜 관련 템플릿 변수들
  • execution_date, data_interval_start/end의 차이점과 장단점
  • Jinja 템플릿 문법
  • 실제 예제: 날짜 기반 API 호출, 파일명 생성
  • pendulum 라이브러리와의 활용

2. Airflow의 날짜 개념 이해하기

2-1. start_date vs execution_date

항목 설명
start_date DAG이 언제부터 실행 가능한지를 설정하는 값 (설정값)
execution_date DAG이 어떤 논리적 날짜의 데이터를 처리하는지를 의미하는 값
DAG(
  dag_id="daily_job",
  start_date=datetime(2025, 4, 1),
  schedule_interval="@daily",
  catchup=True
)

이 경우, Airflow는 2025-04-01T00:00:00부터 매일 DAG을 실행하고, 실제로는 다음 날 자정 즈음 실행되며, execution_date는 “전날 기준”이 됨.

DAG 실행 시점 execution_date 의미
2025-04-02 00:00 2025-04-01 2025-04-01 데이터 처리

2-2. data_interval_start / data_interval_end

Airflow 2.2 이후 등장한 개념으로, execution_date보다 더 명확한 데이터 처리 범위를 표현함.

항목 설명
data_interval_start 처리 구간의 시작 시점
data_interval_end 처리 구간의 끝 시점

예시:

  • execution_date: 2025-04-01
  • data_interval_start: 2025-04-01 00:00
  • data_interval_end: 2025-04-02 00:00

왜 더 나은거임??

  • execution_date는 단일 시점이라 그 자체로는 시작~끝 구간을 명확히 표현하기 어려움
  • data_interval_start, end시간 범위가 명확해서 쿼리 조건, API 요청, 파일명 등 다양한 작업에 더 적합함
  • 백필이나 재실행 시에도 재현성이 뛰어나고 가독성이 좋아짐
  • 특히 pendulum과 조합하면 더 유연한 구간 조정이 가능

3. Jinja 템플릿 기본 문법

Airflow는 내부적으로 Jinja2 템플릿 엔진을 사용해 템플릿을 렌더링함.

3-1. 기본 문법

{{ 변수 }} → 변수 값 출력
{% if 조건문 %} ~ {% endif %} → 조건 분기
{% for item in list %} ~ {% endfor %} → 반복문

3-2. Airflow에서 사용 가능한 주요 템플릿 변수들

변수명 설명 예시
{{ ds }} execution_date의 YYYY-MM-DD 형태 2025-04-01
{{ ds_nodash }} dash 없는 날짜 20250401
{{ execution_date }} datetime 객체 2025-04-01T00:00:00+00:00
{{ data_interval_start }} interval 시작 시점 2025-04-01T00:00:00+00:00
{{ data_interval_end }} interval 끝 시점 2025-04-02T00:00:00+00:00
{{ macros.timedelta(days=7) }} 날짜 연산 헬퍼 함수 execution_date - 7일
{{ params.xxx }} 사용자 정의 파라미터 {{ params.filename }}

4. 실전 예제: 날짜 기반 API 호출

4-1. BashOperator에서 API 호출

fetch_events = BashOperator(
    task_id="fetch_events",
    bash_command=(
        "curl -o /data/events.json \"http://api.com/events?"
        "start_date={{ data_interval_start.strftime('%Y-%m-%d') }}&"
        "end_date={{ data_interval_end.strftime('%Y-%m-%d') }}\""
    ),
    dag=dag
)
  • data_interval_startdata_interval_end를 이용해 정확한 기간의 데이터를 가져옴
  • 백필, 스케줄 등 다양한 상황에서도 안정적

5. 고급 Jinja 문법: if, for, macros, params

5-1. 조건문 (if)

{% if execution_date.day == 1 %}
echo "월초 작업"
{% else %}
echo "일반 작업"
{% endif %}

5-2. 반복문 (for)

{% for table in ['users', 'orders'] %}
echo "처리 중: {{ table }}"
{% endfor %}

5-3. 매크로 사용

{{ macros.ds_add(ds, -7) }}  → 7일 전 날짜 계산
{{ macros.uuid() }} → 유니크 ID 생성

5-4. 사용자 파라미터 (params)

BashOperator(
  task_id="hello",
  bash_command="echo {{ params.name }}",
  params={"name": "찬영"},
  dag=dag
)

6. pendulum 활용

Airflow는 내부 datetime 연산에 pendulum이라는 타임존 지원 강화된 datetime 라이브러리를 사용함.

주요 특징

  • 기본 datetime보다 직관적인 API (.add(), .subtract(), .to_date_string() 등)
  • 타임존을 명확히 다루며, UTC 기반 스케줄에도 유리
{{ data_interval_end.subtract(days=7).to_date_string() }}

data_interval_end 기준으로 7일 전의 날짜를 문자열로 반환 (YYYY-MM-DD)

실전 활용 예시

start={{ data_interval_end.subtract(days=7).to_date_string() }}&
end={{ data_interval_end.to_date_string() }}

→ 최근 7일간 데이터를 수집하는 API 쿼리 생성 가능


7. 정리

개념 설명
execution_date DAG이 처리해야 하는 논리적 날짜 (대개 하루 전)
data_interval_start / end 데이터 범위를 명확히 지정 (Airflow 2.2+ 권장 방식)
Jinja 템플릿 bash/sql 등에서 동적 값 처리 시 사용됨
pendulum 날짜 계산과 포맷에 유리한 내부 라이브러리

Airflow는 DAG의 자동화뿐 아니라, 템플릿 기반 처리도 핵심이기 때문에 템플릿의 개념과 날짜 변수의 차이를 정확히 이해하고 사용하는 것이 매우 중요하다고 한다~~

댓글남기기