where
where
where는 테스트 대상 리소스(모델, 소스, 시드, 스냅샷)를 필터링하는 config예요. where 조건은 리소스 참조를 서브쿼리로 바꿔서 테스트 쿼리에 템플릿으로 주입돼요.
출처: 문서
본문
Definition
테스트 대상 리소스(모델, 소스, 시드, 스냅샷)를 필터링해요.
where 조건은 리소스 참조를 서브쿼리로 바꿔 테스트 쿼리에 템플릿으로 주입돼요. 예를 들어 not_null 테스트는 다음과 같을 수 있어요.
select *
from my_model
where my_column is null
where config를 where date_column = current_date로 설정하면 테스트 쿼리는 이렇게 바뀌어요.
select *
from (select * from my_model where date_column = current_date) dbt_subquery
where my_column is null
Examples
generic(schema) 테스트의 특정 인스턴스 구성:
models/.yml
models:
- name: large_table
columns:
- name: my_column
data_tests:
- accepted_values:
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
values: ["a", "b", "c"]
config:
where: "date_column = current_date"
- name: other_column
data_tests:
- not_null:
config:
where: "date_column < current_date"
이 config는 일회성(one-off) 테스트에서는 무시돼요.
테스트 블록(definition) 안에서 config를 설정하면 generic(schema) 테스트의 모든 인스턴스 기본값이 돼요.
macros/.sql
{% test <testname>(model, column_name) %}
{{ config(where = "date_column = current_date") }}
select ...
{% endtest %}
패키지/프로젝트의 모든 테스트 기본값 설정:
dbt_project.yml
data_tests:
+where: "date_column = current_date"
<package_name>:
+where: >
date_column = current_date
and another_column is not null
Custom logic
where config의 렌더링 컨텍스트는 .yml 파일에 정의된 다른 모든 config와 같아요. {{ var() }}와 {{ env_var() }}는 접근할 수 있지만, 이 config를 설정하기 위한 커스텀 매크로에는 접근할 수 없어요. 특정 테스트의 where 필터를 템플릿화하기 위해 커스텀 매크로를 쓰고 싶다면 우회 방법이 있어요.
dbt는 get_where_subquery 매크로를 정의해요.
dbt는 generic 테스트 정의의 {{ model }}을 {{ get_where_subquery(relation) }}로 바꿔요. 여기서 relation은 테스트 대상 리소스의 ref() 또는 source()예요. 이 매크로의 기본 구현은 다음을 반환해요.
whereconfig가 정의되지 않았을 때{{ relation }}(ref()또는source())whereconfig가 정의됐을 때(select * from {{ relation }} where {{ where }}) dbt_subquery
이 동작을 다음과 같이 재정의할 수 있어요.
- 루트 프로젝트에 커스텀
get_where_subquery를 정의 - 패키지나 어댑터 플러그인에 커스텀
__get_where_subquery디스패치 후보를 정의
이 매크로 정의 안에서는 config의 정적 입력을 기반으로 원하는 커스텀 매크로를 참조할 수 있어요. 가장 단순하게는, 여러 .yml 파일에 걸쳐 반복해야 했던 코드를 DRY할 수 있어요. get_where_subquery 매크로는 런타임에 해석되므로, 커스텀 매크로는 내부 조회(introspective) 데이터베이스 쿼리 결과를 가져오는 것도 포함할 수 있어요.
Example
dbt의 크로스 플랫폼 dateadd() 유틸리티 매크로를 사용해 테스트를 지난 N일 데이터로 필터링해요. 일수는 플레이스홀더 문자열에 설정할 수 있어요.
models/config.yml
models:
- name: my_model
columns:
- name: id
data_tests:
- unique:
config:
where: "date_column > __3_days_ago__" # placeholder string for static config
macros/custom_get_where_subquery.sql
{% macro get_where_subquery(relation) -%}
{% set where = config.get('where') %}
{% if where %}
{% if "_days_ago__" in where %}
{# replace placeholder string with result of custom macro #}
{% set where = replace_days_ago(where) %}
{% endif %}
{%- set filtered -%}
(select * from {{ relation }} where {{ where }}) dbt_subquery
{%- endset -%}
{% do return(filtered) %}
{%- else -%}
{% do return(relation) %}
{%- endif -%}
{%- endmacro %}
{% macro replace_days_ago(where_string) %}
{# Use regex to search the pattern for the number days #}
{# Default to 3 days when no number found #}
{% set re = modules.re %}
{% set days = 3 %}
{% set pattern = '__(\d+)_days_ago__' %}
{% set match = re.search(pattern, where_string) %}
{% if match %}
{% set days = match.group(1) | int %}
{% endif %}
{% set n_days_ago = dbt.dateadd('day', -days, current_timestamp()) %}
{% set result = re.sub(pattern, n_days_ago, where_string) %}
{{ return(result) }}
{% endmacro %}
더 알아보기 (Learn more)
- Data test configurations — 데이터 테스트 설정 개요.
- Generic tests — generic/singular 테스트.