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.sql을analytics_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로 추측해요.
관련 문서 (Related docs)
더 알아보기 (Learn more)
- dbt State 설정 — dbt State의 전체 설정 목록
- defer — deferral 선택 구문