data_tests 속성
data_tests 속성
data_tests 속성은 컬럼, 테이블, 또는 뷰에 대한 단언(assertion)을 정의해요. 이름으로 참조되는 제네릭 데이터 테스트 목록을 담으며, dbt에 내장된 네 가지 제네릭 테스트를 포함할 수 있어요.
출처: 문서
본문
Description
data_tests 속성은 컬럼, 테이블, 또는 뷰에 대한 단언을 정의해요. 이 속성은 이름으로 참조되는 제네릭 데이터 테스트 목록을 포함하며, dbt에 내장된 네 가지 제네릭 테스트를 포함할 수 있어요. 예를 들어 컬럼에 중복이 없고 null 값이 0개인지 확인하는 데이터 테스트를 추가할 수 있어요. 해당 데이터 테스트에 전달되는 인자나 구성은 arguments 속성 아래에 중첩해야 해요.
이 데이터 테스트들이 정의되면 dbt test를 실행해 정확성을 검증할 수 있어요.
시작하는 데 도움이 되도록 아래 예시는 다양한 리소스 타입(모델, 소스, 시드, 스냅샷, 분석)에서 data_tests 속성을 정의하는 방법을 보여줘요.
Models / Sources / Seeds / Snapshots / Analyses
models/<filename>.yml
models:
- name: <model_name>
data_tests:
- <test_name>:
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
<argument_name>: <argument_value>
config:
<test_config>: <config-value>
columns:
- name: <column_name>
data_tests:
- <test_name>
- <test_name>:
arguments:
<argument_name>: <argument_value>
config:
<test_config>: <config-value>
models/<filename>.yml
sources:
- name: <source_name>
tables:
- name: <table_name>
data_tests:
- <test_name>
- <test_name>:
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
<argument_name>: <argument_value>
config:
<test_config>: <config-value>
columns:
- name: <column_name>
data_tests:
- <test_name>
- <test_name>:
arguments:
<argument_name>: <argument_value>
config:
<test_config>: <config-value>
seeds/<filename>.yml
seeds:
- name: <seed_name>
data_tests:
- <test_name>
- <test_name>:
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
<argument_name>: <argument_value>
config:
<test_config>: <config-value>
columns:
- name: <column_name>
data_tests:
- <test_name>
- <test_name>:
arguments:
<argument_name>: <argument_value>
config:
<test_config>: <config-value>
snapshots/<filename>.yml
snapshots:
- name: <snapshot_name>
data_tests:
- <test_name>
- <test_name>:
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
<argument_name>: <argument_value>
config:
<test_config>: <config-value>
columns:
- name: <column_name>
data_tests:
- <test_name>
- <test_name>:
arguments:
<argument_name>: <argument_value>
config:
<test_config>: <config-value>
이 기능은 analyses에는 구현되지 않았어요.
Out-of-the-box data tests
dbt를 사용하는 모든 사람에게 바로 사용할 수 있는 제네릭 데이터 테스트는 네 가지예요.
not_null
이 데이터 테스트는 컬럼에 null 값이 없는지 검증해요.
models/<filename>.yml
models:
- name: orders
columns:
- name: order_id
data_tests:
- not_null
...
테스트 입력용 arguments 블록과 severity나 where 같은 옵션용 config 블록을 추가할 수 있어요. 전체 목록은 Data test configurations를 참고해 주세요. 테스트 인자에 대한 폐기 경고가 보이면 Deprecations에서 테스트 관련 경고를 확인하세요.
unique
이 데이터 테스트는 필드에 중복 값이 없는지 검증해요.
config와 where 절은 선택적이에요.
models/<filename>.yml
models:
- name: orders
columns:
- name: order_id
data_tests:
- unique:
config:
where: "order_id > 21"
accepted_values
이 데이터 테스트는 컬럼의 모든 비- null 값이 제공된 values 목록에 있는지 검증해요. 목록에 없는 값이 있으면 데이터 테스트가 실패해요.
accepted_values 테스트는 선택적 quote 파라미터를 지원하며, 기본적으로 테스트 쿼리의 허용 값 목록을 작은따옴표로 감싸요. 정수나 불리언 같은 비-문자열을 테스트하려면 quote 구성을 명시적으로 false로 설정하세요.
schema.yml
models:
- name: orders
columns:
- name: status
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: ['placed', 'shipped', 'completed', 'returned']
- name: status_id
data_tests:
- accepted_values:
arguments:
values: [1, 2, 3, 4]
quote: false
relationships
이 데이터 테스트는 자식 테이블의 모든 레코드가 부모 테이블에 대응하는 레코드를 갖고 있는지 검증해요. 이 속성을 "참조 무결성(referential integrity)"이라고 불러요. 이 테스트는 데이터베이스 외래 키 제약과 일관되게 NULL 값을 자동으로 검증에서 제외해요. NULL 값이 실패를 일으켜야 한다면 not_null 테스트를 별도로 사용하세요.
다음 예시는 모든 주문의 customer_id가 유효한 customer로 매핑되는지 테스트해요.
schema.yml
models:
- name: orders
columns:
- name: customer_id
data_tests:
- relationships:
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
to: ref('customers')
field: id
to 인자는 Relation을 받아요. 즉 모델에 대한 ref(예: ref('customers'))나 source(예: source('jaffle_shop', 'customers'))를 전달할 수 있어요.
Additional examples
표현식 테스트하기
어떤 데이터 테스트는 여러 컬럼을 필요로 해서 columns: 키 아래에 중첩하는 게 적절하지 않아요. 이런 경우 모델(또는 소스, 시드, 스냅샷)에 데이터 테스트를 적용하면 돼요.
models/orders.yml
models:
- name: orders
description:
Order overview data mart, offering key details for each order including if it's a customer's first order and a food vs. drink item breakdown. One row per order.
data_tests:
- dbt_utils.expression_is_true:
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
expression: "order_items_subtotal = subtotal"
- dbt_utils.expression_is_true:
arguments:
expression: "order_total = subtotal + tax_paid"
이 예시는 order_items_subtotal이 subtotal과 같은지, order_total이 subtotal과 tax_paid를 올바르게 합산하는지 검증하는 표현식 테스트에 초점을 둬요.
커스텀 제네릭 데이터 테스트 사용하기
자체 커스텀 제네릭 데이터 테스트를 정의했다면 그 테스트를 test_name으로 사용할 수 있어요:
models/<filename>.yml
models:
- name: orders
columns:
- name: order_id
data_tests:
- primary_key # name of my custom generic test
커스텀 제네릭 데이터 테스트 작성 가이드를 참고해 주세요.
커스텀 데이터 테스트 이름
기본적으로 dbt는 다음을 연결(concatenate)해 제네릭 데이터 테스트의 이름을 합성해요:
- 테스트 이름(
not_null,unique등) - 모델 이름(또는 소스/시드/스냅샷)
- 컬럼 이름(해당하는 경우)
- 인자(해당하는 경우, 예:
accepted_values의values)
데이터 테스트의 구성은 포함되지 않아요. 연결된 이름이 너무 길면 dbt는 잘라서 해시한 버전을 사용해요. 목표는 테스트를 포함해 프로젝트의 모든 리소스에 고유한 식별자를 유지하는 거예요.
특정 데이터 테스트에 대해 name 속성으로 직접 이름을 정의할 수도 있어요.
언제 유용할까요? dbt의 기본 방식은 이상하거나(그리고 못생긴) 데이터 테스트 이름을 만들 수 있어요. 커스텀 이름을 정의하면 로그 메시지와 메타데이터 아티팩트에서 데이터 테스트가 어떻게 표시될지 완전히 제어할 수 있어요. 또한 그 이름으로 데이터 테스트를 선택할 수도 있어요.
models/<filename>.yml
models:
- name: orders
columns:
- name: status
data_tests:
- accepted_values:
name: unexpected_order_status_today
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
values: ['placed', 'shipped', 'completed', 'returned']
config:
where: "order_date = current_date"
$ dbt test --select unexpected_order_status_today
12:43:41 Running with dbt=1.1.0
12:43:41 Found 1 model, 1 test, 0 snapshots, 0 analyses, 167 macros, 0 operations, 1 seed file, 0 sources, 0 exposures, 0 metrics
12:43:41
12:43:41 Concurrency: 5 threads (target='dev')
12:43:41
12:43:41 1 of 1 START test unexpected_order_status_today ................................ [RUN]
12:43:41 1 of 1 PASS unexpected_order_status_today ...................................... [PASS in 0.03s]
12:43:41
12:43:41 Finished running 1 test in 0.13s.
12:43:41
12:43:41 Completed successfully
12:43:41
12:43:41 Done. PASS=1 WARN=0 ERROR=0 SKIP=0 TOTAL=1
데이터 테스트의 이름은 주어진 모델-컬럼 조합에 정의된 모든 테스트에서 고유해야 해요. 여러 다른 컬럼이나 여러 다른 모델에 정의된 데이터 테스트에 같은 이름을 주면 dbt test --select <repeated_custom_name>이 전부 선택해요.
언제 필요할까요? 구성만 다르게 같은 데이터 테스트를 두 번 정의한 경우 dbt는 이 데이터 테스트들을 중복으로 간주해요:
models/<filename>.yml
models:
- name: orders
columns:
- name: status
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: ['placed', 'shipped', 'completed', 'returned']
config:
where: "order_date = current_date"
- accepted_values:
arguments:
values: ['placed', 'shipped', 'completed', 'returned']
config:
# only difference is in the 'where' config
where: "order_date = (current_date - interval '1 day')" # PostgreSQL syntax
Compilation Error
dbt found two tests with the name "accepted_values_orders_status__placed__shipped__completed__returned" defined on column "status" in "models.orders".
Since these resources have the same name, dbt will be unable to find the correct resource
when running tests.
To fix this, change the name of one of these resources:
- test.testy.accepted_values_orders_status__placed__shipped__completed__returned.69dce9e5d5 (models/one_file.yml)
- test.testy.accepted_values_orders_status__placed__shipped__completed__returned.69dce9e5d5 (models/one_file.yml)
커스텀 이름을 제공하면 dbt가 데이터 테스트를 구분하도록 도와줘요:
models/<filename>.yml
models:
- name: orders
columns:
- name: status
data_tests:
- accepted_values:
name: unexpected_order_status_today
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
values: ['placed', 'shipped', 'completed', 'returned']
config:
where: "order_date = current_date"
- accepted_values:
name: unexpected_order_status_yesterday
arguments:
values: ['placed', 'shipped', 'completed', 'returned']
config:
where: "order_date = (current_date - interval '1 day')" # PostgreSQL
$ dbt test
12:48:03 Running with dbt=1.1.0-b1
12:48:04 Found 1 model, 2 tests, 0 snapshots, 0 analyses, 167 macros, 0 operations, 1 seed file, 0 sources, 0 exposures, 0 metrics
12:48:04
12:48:04 Concurrency: 5 threads (target='dev')
12:48:04
12:48:04 1 of 2 START test unexpected_order_status_today ................................ [RUN]
12:48:04 2 of 2 START test unexpected_order_status_yesterday ............................ [RUN]
12:48:04 1 of 2 PASS unexpected_order_status_today ...................................... [PASS in 0.04s]
12:48:04 2 of 2 PASS unexpected_order_status_yesterday .................................. [PASS in 0.04s]
12:48:04
12:48:04 Finished running 2 tests in 0.21s.
12:48:04
12:48:04 Completed successfully
12:48:04
12:48:04 Done. PASS=2 WARN=0 ERROR=0 SKIP=0 TOTAL=2
store_failures를 사용한다면: dbt는 각 데이터 테스트의 이름을 실패 레코드를 저장하는 테이블의 이름으로 사용해요. 한 데이터 테스트에 커스텀 이름을 정의했다면 그 커스텀 이름이 실패 테이블의 이름으로도 사용돼요. 데이터 테스트에 alias를 선택적으로 구성해서, 데이터 테스트의 이름(메타데이터용)과 데이터베이스 테이블의 이름(실패 저장용)을 각각 제어할 수 있어요.
테스트 정의의 대체 형식
여러 인자와 구성을 가진 제네릭 데이터 테스트를 정의할 때 YAML이 지저분해 보이고 느껴질 수 있어요. 더 편하다면 데이터 테스트 이름을 test_name으로 제공해서 단일 딕셔너리의 최상위 키로 같은 데이터 테스트 속성을 정의할 수도 있어요. 전적으로 선택이에요.
이 예시는 위 예시와 동일해요:
models/<filename>.yml
models:
- name: orders
columns:
- name: status
data_tests:
- name: unexpected_order_status_today
test_name: accepted_values # name of the generic test to apply
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
values:
- placed
- shipped
- completed
- returned
config:
where: "order_date = current_date"
더 알아보기 (Learn more)
- Data testing guide — 데이터 테스트 개념과 작성법
- Data test configurations — 테스트 구성 옵션