ref 함수

ref 함수

select * from {{ ref("node_name") }}

dbt에서 가장 중요한 함수가 ref()예요. 이 함수 없이는 조금만 복잡한 모델도 만들 수 없을 정도예요. ref()는 한 모델 안에서 다른 모델을 참조하는 방법이에요.

출처: 문서

본문

정의

이 함수는:

  • model, seed, 또는 snapshot에 대한 Relation을 반환해요
  • 참조된 노드와 현재 모델 사이에 의존성(dependency)을 만들어요. 문서화와 노드 선택에 유용해요
  • 데이터베이스에서 전체 객체 이름으로 컴파일돼요

보통 모델은 서로 "쌓아 올리는(stacked)" 구조로 만들어지기 때문에, 이 참조는 아주 흔한 동작이에요. 실제로는 이렇게 생겼어요:

model_a.sql

select *
from public.raw_data

model_b.sql

select *
from {{ref('model_a')}}

ref()는 내부적으로 두 가지 중요한 일을 해요. 첫째, 모델 파일에 스키마를 보간(interpolate)해서 구성(configuration)으로 배포 스키마를 바꿀 수 있게 해줘요. 둘째, 모델 간의 이 참조를 사용해 의존성 그래프를 자동으로 만들어요. 이 덕분에 dbt run을 쓸 때 dbt가 모델을 올바른 순서로 배포할 수 있어요.

{{ ref }} 함수는 {{ this }} 변수와 같은 table, schema, name 속성을 가진 Relation 객체를 반환해요.

고급 ref 사용법

버전 지정 ref

ref 함수는 선택적 키워드 인자 version(또는 v)을 지원해요. ref 함수에 버전 인자를 주면, dbt는 참조된 모델의 지정된 버전에 해당하는 Relation 객체를 반환해요.

이 기능은 새 버전을 만들어 breaking change를 도입하는 버전 모델을 참조할 때 유용해요. 기존 버전의 모델에는 breaking change가 없음을 보장하거든요.

버전 모델의 refversion 인자를 주지 않으면 최신 버전이 사용돼요. 이렇게 하면 참조된 모델의 최신 변경 사항이 자동으로 반영되는 이점이 있지만, breaking change가 포함될 위험도 있어요.

예시

models/.yml


models:
  - name: model_name
    latest_version: 2
    versions:
      - v: 2
      - v: 1
 -- returns the `Relation` object corresponding to version 1 of model_name
select * from {{ ref('model_name', version=1) }}
 -- returns the `Relation` object corresponding to version 2 (the latest version) of model_name
select * from {{ ref('model_name') }}

프로젝트별 모델 참조

ref 함수의 두 인자 변형을 사용하면 다른 프로젝트의 모델도 참조할 수 있어요. 네임스페이스(프로젝트나 패키지가 될 수 있음)와 모델 이름을 모두 지정하면 명확성이 보장되고 ref에서 모호함을 피할 수 있어요. 여러 프로젝트나 패키지에 걸친 모델을 다룰 때도 유용해요.

프로젝트(패키지가 아닌)와 함께 두 인자를 사용할 때는 cross project dependencies도 설정해야 해요.

다음 구문은 특정 프로젝트나 패키지의 모델을 참조하는 방법을 보여줘요:

select * from {{ ref('project_or_package', 'model_name') }}

다른 패키지나 프로젝트에 정의된 모델을 참조할 때는 항상 두 인자 ref를 사용하는 걸 권장해요. 모든 경우에 필수는 아니지만, 코드를 보는 사람과 dbt, 미래의 독자에게 더 명확하기 때문이에요.

모델 이름이 여러 프로젝트나 설치된 패키지에 걸쳐 중복되는 경우, 모호함을 피하기 위해 특히 두 인자 ref를 사용하는 걸 권장해요. 한 인자 ref(모델 이름만)를 쓰면 dbt는 같은 네임스페이스(패키지 또는 프로젝트)에서 그 이름의 모델을 찾고, 없으면 에러를 발생시켜요.

(앱: dbt v1.12 이상)

최신 SL YAML 스펙의 크로스 프로젝트 ref 미지원dbt MeshSemantic Layer와 함께 쓸 때, 다른 프로젝트의 모델 참조는 semantic model이 최상위 리소스로 정의되어 프로젝트 간 모델을 참조할 수 있는 레거시 YAML 스펙에서만 지원돼요. 최신 YAML 스펙에서는 semantic model이 모델 YAML 파일 안에 정의되며 크로스 프로젝트 참조는 아직 지원되지 않아요. 최신 스펙의 이 기능 지원은 향후 릴리스에서 계획되어 있어요.

참고: project_or_packagedbt_project.yml에 정의된 프로젝트/패키지의 name과 일치해야 해요. 이 값은 저장소 이름과 다를 수 있어요. 저장소의 조직 이름은 절대 포함하지 않아요. 예를 들어 fivetran/stripe 패키지를 쓰면 패키지 이름은 stripe이지 fivetran/stripe가 아니에요.

의존성 강제하기

일반적인 사용에서 dbt는 파싱 단계에서 모든 모델을 발견하기 때문에 ref 함수 사용에 따라 실행 순서를 정확히 알아요. dbt는 런타임에 "예상치 못한" ref(파싱 중에 숨겨져 있던 것)를 발견하면 에러를 던져요. 가장 흔한 원인은 그 ref가 파싱 중에 평가되지 않은 if 문의 분기 안에 있는 경우예요.

conditional_ref.sql

--This macro already has its own `if execute` check, so this one is redundant and introduced solely to cause an error
{% if execute %}
  {% set sql_statement %}
      select max(created_at) from {{ ref('processed_orders') }}
  {% endset %}

  {%- set newest_processed_order = dbt_utils.get_single_value(sql_statement, default="'2020-01-01'") -%}
{% endif %}

select

    *,
    last_order_at > '{{ newest_processed_order }}' as has_unprocessed_order

from {{ ref('users') }}
  • 이 경우 파싱 중 execute가 false라서 dbt는 processed_orders가 의존성인지 알지 못해요.
  • 이를 해결하려면 ref 함수와 함께 SQL 주석을 사용해요. 그러면 dbt가 의존성을 이해하고 컴파일된 쿼리도 여전히 유효해요:

conditional_ref.sql

--Now that this ref is outside of the if block, it will be detected during parsing
--depends_on: {{ ref('processed_orders') }}

{% if execute %}
  {% set sql_statement %}
      select max(created_at) from {{ ref('processed_orders') }}
  {% endset %}

  {%- set newest_processed_order = dbt_utils.get_single_value(sql_statement, default="'2020-01-01'") -%}
{% endif %}

select

    *,
    last_order_at > '{{ newest_processed_order }}' as has_unprocessed_order

from {{ ref('users') }}

— dbt가 의존성을 이해하게 하려면 Jinja 주석 대신 SQL 주석을 사용해요. Jinja 주석({# ... #})은 동작하지 않고 dbt 파서가 무시해서 ref가 처리·해결되지 않아요. 반면 SQL 주석(-- 또는 /* ... */)은 동작해요. dbt는 SQL 주석 안에서도 Jinja를 여전히 평가하거든요.

더 알아보기 (Learn more)

  • ref()는 모델 의존성 그래프 구축과 올바른 실행 순서 보장의 핵심이에요.
  • 관련 개념: this, source, Relation 객체.