defer_to_target

defer_to_target

defer_to_target는 dbt State가 미선택 업스트림 노드와 모델의 재빌드 여부를 판단할 때 어느 타깃 환경으로 deferral할지를 지정하는 프로필 설정이에요. 셀프 매니지드 배포에서 다중 환경을 운영할 때 타깃마다 다른 업스트림 환경을 가리키게 구성할 수 있죠.

출처: 문서

본문

셀프 매니지드 배포 전용 — 이 설정은 셀프 매니지드 dbt 배포에 적용돼요. dbt 플랫폼을 사용한다면 deferral은 UI의 환경 설정을 통해 구성해요.

defer_to_target은 dbt State의 일부로, 환경 간 모델 캐싱과 deferral을 관리해요.

my_project:
  outputs:
    dev:
      type: snowflake
      # ... dev connection settings
    staging:
      type: snowflake
      # ... staging connection settings
    uat:
      type: snowflake
      # ... uat connection settings
      defer_to_target: staging
    prod:
      type: snowflake
      # ... prod connection settings
  target: prod

정의 (Definition)

defer_to_target은 미선택 업스트림 노드를 해석하고 모델을 재빌드할 필요가 있는지 평가할 때 dbt State가 deferral할 타깃 환경을 지정해요.

셀프 매니지드 배포에서 여러 환경을 운영하는 경우, 각 타깃이 서로 다른 업스트림 환경으로 deferral하도록 구성할 수 있어요. 예를 들어 uat 환경은 staging으로 deferral하고, prod는 자체 상태를 독립적으로 관리하는 식이에요.

기본값 (Default)

prod. 생략하면 모든 타깃이 prod라는 이름의 타깃으로 deferral해요. 다른 타깃(예: staging)으로 deferral하고 싶거나, 프로덕션 타깃 이름이 prod가 아닐 때(예: production) 이 설정을 사용해요.

예시 (Example)

다중 환경 deferral 체인

uat가 staging으로 deferral하는 파이프라인을 구성해 볼게요:

my_project:
  outputs:
    dev:
      type: snowflake
      account: abc12345
      database: ANALYTICS
      schema: DBT_DEV
    staging:
      type: snowflake
      account: abc12345
      database: ANALYTICS
      schema: DBT_STAGING
    uat:
      type: snowflake
      account: abc12345
      database: ANALYTICS
      schema: DBT_UAT
      defer_to_target: staging
    prod:
      type: snowflake
      account: abc12345
      database: ANALYTICS
      schema: DBT_PROD
  target: prod

manifest 없이 dbt State를 쓸 때의 주의사항 (Caveats)

dbt State가 관계(relation)의 프로덕션 버전이 어디에 빌드됐는지 추측할 때, defer_to_target의 구성 타깃으로 데이터베이스와 스키마 이름을 다시 렌더링해요.

만약 생성된 이름 중 하나가 프로덕션 실행 이후 바뀐 동적 데이터에 의존하거나, 노드의 별칭(alias)이 타깃별 로직을 사용한다면:

  • 추측한 위치가 존재하지 않아 불필요한 처음부터 재빌드를 강제할 수 있어요.
  • 추측한 위치가 잘못된 객체를 가리켜 무효한 데이터가 생길 수 있어요.

아래 예시는 orders 노드에서 문제가 생기는 시나리오들이에요. dev 프로필은 schema: dbt_developer, prod 프로필은 schema: analytics를 설정한다고 가정해요.

환경 변수와 CLI 변수

스키마 이름이 환경 변수나 CLI 변수에 의존한다면, 프로덕션과 로컬 실행 간 값이 달라서 dbt State가 잘못된 위치를 추측할 수 있어요.

{% macro generate_schema_name(custom_schema_name, node) %}
    {{ target.schema }}_{{ env_var('DBT_BRANCH', 'main') | replace('/', '_') }}
{% endmacro %}
  • 프로덕션은 DBT_BRANCH=main으로 실행되므로 관계는 analytics_main.orders에 빌드돼요.
  • 개발자가 DBT_BRANCH=feature/x로 실행하면 dbt State는 target.schema를 prod 값(analytics)으로 바꾸지만 DBT_BRANCH는 개발자 셸에서 읽어 analytics_feature_x.orders로 추측해요.
  • 그 관계는 프로덕션에 존재하지 않으므로 복제가 수행되지 않고 노드가 처음부터 재빌드돼요.

CLI 변수에서도 같은 문제가 발생해요:

{% macro generate_schema_name(custom_schema_name, node) %}
    {{ target.schema }}_{{ var('environment', 'dev') }}
{% endmacro %}
  • 프로덕션은 dbt run --vars '{environment: prod}'로 실행되므로 관계는 analytics_prod.orders에 빌드돼요.
  • 개발자가 --vars 없이 dbt run을 실행하면 var('environment')가 기본값(dev)으로 폴백되어 dbt State는 analytics_dev.orders를 추측해요.
  • 그 관계는 프로덕션에 존재하지 않아요. 원래 프로덕션 호출에서 전달된 vars는 dbt State가 복구할 수 있는 곳에 저장되지 않아요.

파일이 이동할 때 경로에서 파생된 이름

노드의 디렉터리를 스키마로 사용하는 패턴이 흔해요:

{% macro generate_schema_name(custom_schema_name, node) %}
    {{ target.schema }}_{{ node.fqn[-2] }}
{% endmacro %}
  • 프로덕션은 models/finance/orders.sqlanalytics_finance.orders로 빌드해요.
  • 개발자가 프로젝트를 재구성해 디렉터리를 models/accounting/으로 바꾸고 dbt run -s orders를 실행하면, 로컬 manifest는 노드의 부모 디렉터리를 accounting으로 기록해요. dbt State는 analytics_accounting.orders를 추측해요.
  • 프로덕션은 여전히 analytics_finance.orders에 있으므로 복제가 빗나가고 노드가 처음부터 재빌드돼요.

타깃별 generate_alias_name 로직

데이터베이스·스키마와 달리 dbt State는 현재 별칭(alias)을 다시 렌더링하지 않아요. 타깃이나 환경에 따라 달라지는 generate_alias_name 오버라이드는 추측을 깨뜨려요.

{% macro generate_alias_name(custom_alias_name=none, node=none) %}
    {%- if custom_alias_name -%}
        {{ custom_alias_name | trim }}_{{ target.name }}
    {%- else -%}
        {{ node.name }}_{{ target.name }}
    {%- endif -%}
{% endmacro %}
  • target.name == 'prod'일 때 프로덕션은 analytics.orders_prod를 빌드해요.
  • 개발자가 target.name == 'dev'로 실행하면 dbt State는 스키마 요소를 analytics로 바꾸지만 별칭은 그대로 둬서 analytics.orders_dev로 추측해요.

더 알아보기 (Learn more)