Перейти к основному содержимому

Добавление тестов данных в ваш DAG

dbt Copilot доступен в бета-версии
Используйте dbt Copilot, доступный в бета-версии, чтобы генерировать data tests только в dbt Cloud IDE.

Чтобы использовать 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 и определяет один тест данных:

tests/assert_total_payment_amount_is_positive.sql
-- Возвраты имеют отрицательную сумму, поэтому общая сумма всегда должна быть >= 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 со следующим содержимым:

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 — перейдите к документации по пакетам, чтобы узнать больше!

Пример

Чтобы добавить общий (или "схемный") тест в ваш проект:

  1. Добавьте файл .yml в ваш каталог models, например, models/schema.yml, со следующим содержимым (возможно, вам потребуется изменить значения name: для существующей модели)
models/schema.yml
version: 2

models:
- name: orders
columns:
- name: order_id
tests:
- unique
- not_null

  1. Запустите команду 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

  1. Проверьте SQL, который выполняет dbt, либо:
    • dbt Cloud: проверив вкладку Details.
    • dbt Core: проверив каталог target/compiled

Тест на уникальность

select *
from (

select
order_id

from analytics.orders
where order_id is not null
group by order_id
having count(*) > 1

) validation_errors

Тест на отсутствие null

select *
from analytics.orders
where order_id is null

Хранение неудачных тестов

Обычно запрос теста данных вычисляет неудачи в процессе своего выполнения. Если вы установите необязательный флаг --store-failures, конфигурацию store_failures или конфигурацию store_failures_as, dbt сначала сохранит результаты тестового запроса в таблицу в базе данных, а затем выполнит запрос к этой таблице, чтобы вычислить количество неудач.

Этот рабочий процесс позволяет вам быстрее запрашивать и изучать неудачные записи в процессе разработки:

Храните неудачные тесты в базе данных для более быстрого отладки во время разработки.Храните неудачные тесты в базе данных для более быстрого отладки во время разработки.

Обратите внимание, что если вы выберете хранение неудачных тестов:

  • Таблицы результатов тестов создаются в схеме с суффиксом или именем dbt_test__audit по умолчанию. Можно изменить это значение, установив конфигурацию schema. (Для получения более подробной информации о наименовании схем, см. использование пользовательских схем.)
  • Результаты теста всегда заменяют предыдущие неудачи для того же теста.

Новый синтаксис data_tests:

Часто задаваемые вопросы

Какие тесты доступны для использования в dbt?
Как протестировать одну модель за раз?
Один из моих тестов не прошел, как я могу его отладить?
Какие тесты следует добавить в мой проект?
Когда следует запускать тесты?
Могу ли я хранить свои тесты в каталоге, отличном от каталога `tests` в моем проекте?
Как запустить тесты только для источников?
Могу ли я установить пороги срабатывания тестов?
Могу ли я проверить уникальность двух столбцов?
100