Добавление тестов данных в ваш DAG
Чтобы использовать dbt Copilot, у вас должна быть активная учетная запись dbt Cloud Enterprise, и вы должны либо согласиться использовать ключ OpenAI от dbt Labs, либо предоставить свой собственный ключ Open AI API. Зарегистрируйтесь здесь или свяжитесь с командой по работе с клиентами, чтобы присоединиться к закрытой бета-версии.
Связанные справочные документы
Обзор
Тесты данных — это утверждения, которые вы делаете о своих моделях и других ресурсах в вашем проекте dbt (например, источниках, семенах и снимках). Когда вы запускаете dbt test
, dbt сообщит вам, прошел ли каждый тест в вашем проекте или нет.
Вы можете использовать тесты данных для улучшения целостности SQL в каждой модели, делая утверждения о сгенерированных результатах. Из коробки вы можете проверить, содержит ли указанный столбец в модели только ненулевые значения, уникальные значения или значения, которые имеют соответствующее значение в другой модели (например, customer_id
для order
соответствует id
в модели customers
), и значения из указанного списка. Вы можете расширить тесты данных, чтобы они соответствовали бизнес-логике, специфичной для вашей организации — любое утверждение, которое вы можете сделать о своей модели в форме запроса select, может быть преобразовано в тест данных.
Тесты данных возвращают набор записей, не прошедших проверку. Общие тесты данных (ранее известные как тесты схемы) определяются с использованием блоков test
.
Как и почти все в dbt, тесты данных — это SQL-запросы. В частности, это операторы select
, которые стремятся захватить "неудачные" записи, те, которые опровергают ваше утверждение. Если вы утверждаете, что столбец уникален в модели, тестовый запрос выбирает дубликаты; если вы утверждаете, что столбец никогда не бывает пустым, тест ищет пустые значения. Если тест данных возвращает ноль неудачных строк, он проходит, и ваше утверждение подтверждается.
Существует два способа определения тестов данных в dbt:
- Единичный тест данных — это тестирование в его простейшей форме: если вы можете написать SQL-запрос, который возвращает неудачные строки, вы можете сохранить этот запрос в файле
.sql
в вашем каталоге тестов. Теперь это тест данных, и он будет выполнен командойdbt test
. - Общ ий тест данных — это параметризованный запрос, который принимает аргументы. Тестовый запрос определяется в специальном блоке
test
(как макрос). После определения вы можете ссылаться на общий тест по имени в ваших.yml
файлах — определяйте его на моделях, столбцах, источниках, снимках и семенах. dbt поставляется с четырьмя встроенными общими тестами данных, и мы считаем, что вы должны их использовать!
Определение тестов данных — отличный способ подтвердить, что ваши выходные и входные данные соответствуют ожиданиям, и помогает предотвратить регрессии при изменении вашего кода. Поскольку вы можете использовать их снова и снова, делая аналогичные утверждения с небольшими вариациями, общие тесты данных, как правило, гораздо более распространены — они должны составлять основную часть вашего набора тестов данных dbt. Тем не менее, оба способа определения тестов данных имеют свое время и место.
Если вы новичок в dbt, мы рекомендуем вам ознакомиться с нашим руководством по быстрому старту, чтобы создать ваш первый проект dbt с моделями и тестами.
Единичные тесты данных
Самый простой способ определить тест данных — это написать точный SQL, который вернет неудачные записи. Мы называем их "единичными" тестами данных, потому что это одноразовые утверждения, используемые для одной цели.
Эти тесты определяются в файлах .sql
, обычно в вашем каталоге tests
(как определено вашей конфигурацией test-paths
). Вы можете использовать Jinja (включая ref
и source
) в определении т еста, так же как и при создании моделей. Каждый файл .sql
содержит один оператор select
и определяет один тест данных:
-- Возвраты имеют отрицательную сумму, поэтому общая сумма всегда должна быть >= 0.
-- Поэтому возвращаем записи, где total_amount < 0, чтобы тест не прошел.
select
order_id,
sum(amount) as total_amount
from {{ ref('fct_payments') }}
group by 1
having total_amount < 0
Имя этого теста — это имя файла: assert_total_payment_amount_is_positive
.
Обратите внимание, что вам не нужно включать точки с запятой (;) в конце SQL-оператора в ваших файлах единичных тестов, так как это может привести к сбою теста.
Чтобы добавить описание к единичному тесту в вашем проекте, добавьте файл .yml
в ваш каталог tests
, например, tests/schema.yml
со следующим содержимым:
version: 2
data_tests:
- name: assert_total_payment_amount_is_positive
description: >
Возвраты имеют отрицательную сумму, поэтому общая сумма всегда должна быть >= 0.
Поэтому возвращаем записи, где общая сумма < 0, чтобы тест не прошел.
Единичные тесты данных настолько просты, что вы можете обнаружить, что пишете одну и ту же базовую структуру снова и снова, только меняя имя столбца или модели. В этот момент тест уже не так уж и единичен! В этом случае мы рекомендуем общие тесты данных.
Общие тесты данных
Некоторые тесты данных являются общими: их можно использовать снова и снова. Общий тест данных определяется в блоке test
, который содержит параметризованный запрос и принимает аргументы. Он может выглядеть так:
{% test not_null(model, column_name) %}
select *
from {{ model }}
where {{ column_name }} is null
{% endtest %}
Вы заметите, что есть два аргумента, model
и column_name
, которые затем шаблонизируются в запросе. Это делает тест "общим": его можно определить на стольких столбцах, сколько вы хотите, в стольких моделях, сколько вы хотите, и dbt передаст значения model
и column_name
соответственно. После того как этот общий тест был определен, его можно добавить как свойство на любую существующую модель (или источник, семя или снимок). Эти свойства добавляются в .yml
файлы в том же каталоге, что и ваш ресурс.
Если это ваш первый опыт работы с добавлением свойств к ресурсу, ознакомьтесь с документацией по объявлению свойств.
Из коробки dbt поставляется с четырьмя уже определенными общими тестами данных: unique
, not_null
, accepted_values
и relationships
. Вот полный пример использования этих тестов на модели orders
:
version: 2
models:
- name: orders
columns:
- name: order_id
tests:
- unique
- not_null
- name: status
tests:
- accepted_values:
values: ['placed', 'shipped', 'completed', 'returned']
- name: customer_id
tests:
- relationships:
to: ref('customers')
field: id
На простом языке, эти тесты данных переводятся как:
unique
: столбецorder_id
в моделиorders
должен быть уникальнымnot_null
: столбецorder_id
в моделиorders
не должен содержать пустых значенийaccepted_values
: столбецstatus
вorders
должен быть одним из'placed'
,'shipped'
,'completed'
или'returned'
relationships
: каждыйcustomer_id
в моделиorders
существует какid
вcustomers
(также известная как ссылочная целостность)
За кулисами dbt строит select
запрос для каждого теста данных, используя параметризованный запрос из общего блока теста. Эти запросы возвращают строки, где ваше утверждение не является истинным; если тест возвращает ноль строк, ваше утверждение проходит.
Вы можете найти больше информации об этих тестах данных и дополнительных конфигурациях (включая severity
и tags
) в справочном разделе.
Больше общих тестов данных
Эти четыре теста достаточно, чтобы начать. Вы быстро обнаружите, что хотите использовать более разнообразные тесты — это хорошо! Вы также можете установить общие тесты данных из пакета или написать свои собственные, чтобы использовать (и переиспользовать) их в вашем проекте dbt. Ознакомьтесь с руководством по созданию пользовательских общих тестов для получения дополнительной информации.
Существуют общие тесты, определенные в некоторых open-source пакетах, таких как dbt-utils и dbt-expectations — перейдите к документации по пакетам, чтобы узнать больше!
Пример
Чтобы добавить общий (или "схемный") тест в ваш проект:
- Добавьте файл
.yml
в ваш каталогmodels
, например,models/schema.yml
, со следующим содержимым (возможно, вам потребуется изменить значенияname:
для существующей модели)
version: 2
models:
- name: orders
columns:
- name: order_id
tests:
- unique
- not_null
- Запустите
команду dbt test
:
$ dbt test
Found 3 models, 2 tests, 0 snapshots, 0 analyses, 130 macros, 0 operations, 0 seed files, 0 sources
17:31:05 | Concurrency: 1 threads (target='learn')
17:31:05 |
17:31:05 | 1 of 2 START test not_null_order_order_id..................... [RUN]
17:31:06 | 1 of 2 PASS not_null_order_order_id........................... [PASS in 0.99s]
17:31:06 | 2 of 2 START test unique_order_order_id....................... [RUN]
17:31:07 | 2 of 2 PASS unique_order_order_id............................. [PASS in 0.79s]
17:31:07 |
17:31:07 | Finished running 2 tests in 7.17s.
Completed successfully
Done. PASS=2 WARN=0 ERROR=0 SKIP=0 TOTAL=2
- Проверьте SQL, который выполняет dbt, либо:
- dbt Cloud: проверив вкладку Details.
- dbt Core: проверив каталог
target/compiled
Тест на уникальность
- Скомпилированный SQL
- Шаблонизированный SQL
select *
from (
select
order_id
from analytics.orders
where order_id is not null
group by order_id
having count(*) > 1
) validation_errors
select *
from (
select
{{ column_name }}
from {{ model }}
where {{ column_name }} is not null
group by {{ column_name }}
having count(*) > 1
) validation_errors
Тест на отсутствие null
- Скомпилированный SQL
- Шаблонизированный SQL
select *
from analytics.orders
where order_id is null
select *
from {{ model }}
where {{ column_name }} is null
Хранение неудачных тестов
Обычно запрос теста данных вычисляет неудачи в процессе своего выполнения. Если вы установите необязательный флаг --store-failures
, конфигурацию store_failures
или конфигурацию store_failures_as
, dbt сначала сохранит результаты тестового запроса в таблицу в базе данных, а затем выполнит запрос к этой таблице, чтобы вычислить количество неудач.
Этот рабочий процесс позволяет вам быстрее запрашивать и изучать неудачные записи в процессе разработки:
Обратите внимание, что если вы выберете хранение неудачных тестов:
- Таблицы результатов тестов создаются в схеме с суффиксом или именем
dbt_test__audit
по умолчанию. Можно изменить это значение, установив конфигурациюschema
. (Для получения более подробной информации о наименовании схем, см. использование пользовательских схем.)
- Результаты теста всегда заменяют предыдущие неудачи для того же теста.