Проверки
По мере роста проектов dbt и увеличения числа участников, добавляющих модели, поддерживать единые стандарты становится сложнее: модель выпускается без описания, у публичной модели нет владельца, новая модель не соответствует соглашениям об именовании. Ничто из этого не нарушает работу, поэтому остаётся незамеченным, но качество незаметно снижается.
Проверки — это SQL-запросы, которые проверяют соблюдение правил и стандартов для метаданных вашего проекта. Определите правила (например, у каждой модели должно быть описание, должны быть заданы обязательные теги и так далее), и dbt обеспечит их соблюдение до начала любых операций в хранилище данных.
Пишите проверки на SQL для DuckDB, используя макрос {{ info_schema() }} для обращения к dbt Information Schema в запросе. Проверки выполняются локально в DuckDB, поэтому им не требуется подключение к хранилищу данных. Если проект нарушает правило, dbt build останавливается до компиляции или материализации хотя бы одной модели.
Как и тесты данных, проверка находит в проекте все случаи, которые не соответствуют вашим ожиданиям. Проверка проходит успешно, если запрос возвращает ноль строк, и завершается неудачей, если он возвращает одну или несколько строк.
Проверки выполняются автоматически при каждом запуске dbt build; их можно пропустить с помощью --skip-checks. Также их можно запускать по требованию командой dbt check.
Рекомендации по написанию SQL-файлов проверок
В этом разделе описаны правила и ограничения для написания SQL-файлов проверок и настройки их поведения.
- Проверка — это SQL-файл в каталоге
checks/. При необходимости рядом с ним в том же каталоге можно разместить YAML-файл свойств для его настройки. Чтобы использовать другой каталог, задайтеcheck-pathsвdbt_project.yml. - Имя файла без расширения
.sqlстановится именем проверки (например,all_models_have_descriptions— это имя проверки дляchecks/all_models_have_descriptions.sql). - Jinja в файлах проверок обрабатывается на этапе разбора. Вы можете использовать Jinja, но уже на этом этапе результат должен быть корректным SQL для DuckDB; в отличие от моделей, проверки не проходят отдельный этап компиляции.
- Проверки — это ресурсы dbt; каждая проверка присутствует в
manifest.json, поддерживаетtagsиmetaи отображается в выводеdbt ls.
Макрос info_schema()
{{ info_schema() }} — это поддерживаемый способ обращения к dbt Information Schema в проверке. Передайте имя таблицы, к которой хотите выполнить запрос (например, {{ info_schema('models') }} для моделей или {{ info_schema('edges') }} для рёбер DAG). Материализованные файлы Information Schema не требуются; проверки выполняются на основе промежуточного представления, созданного на этапе разбора.
Полный список доступных представлений и столбцов приведён в разделе Столбцы, доступные для проверок.
Создание первой проверки
Следующие шаги помогут вам создать первую проверку.
-
Объявите версию
info_schemaвdbt_project.yml:Параметр
info_schema.versionфиксирует версию info schema, которую использует макрос{{ info_schema() }}. В настоящее время доступна только версия1.dbt_project.ymlinfo_schema:
version: 1 -
Создайте проверку в каталоге
checks/:Используйте
{{ info_schema() }}для запросов к метаданным проекта. Проверка проходит успешно, если запрос возвращает ноль строк. Доступные представления и столбцы перечислены в разделе Столбцы, доступные для проверок.checks/all_models_have_descriptions.sqlselect unique_id
from {{ info_schema('models') }}
where description = '' -
Настройте проверку в YAML-файле свойств в каталоге
checks/.checks/_checks.ymlversion: 2
checks:
- name: all_models_have_descriptions
description: "Завершается неудачей, если у какой-либо модели отсутствует описание."
config:
severity: warn # по умолчанию используется error; 'warn' регистрирует проблемы, но не прерывает выполнение -
Запустите проверки:
dbt check
Примеры проверок
В следующих примерах показаны распространённые правила качества проекта: каждое из них определено как SQL-запрос с использованием макросов info_schema и сохранено в файле .sql в каталоге checks/.
-
Требовать наличия описания у всех моделей с доступом
public:checks/public_models_have_descriptions.sqlselect unique_id
from {{ info_schema('models') }}
where access = 'public'
and description = '' -
Выявлять источники, на которые не ссылаются модели. У такого источника нет зависимых моделей: он либо не используется, либо отсутствует модель, которая должна на него ссылаться:
checks/unused_sources.sqlselect s.unique_id, s.name
from {{ info_schema('sources') }} as s
left join {{ info_schema('edges') }} as e on e.parent_unique_id = s.unique_id
where e.child_unique_id is null -
Выявлять модели с доступом
public, у группы которых не указан владелец:checks/public_models_have_owners.sqlselect m.unique_id
from {{ info_schema('models') }} as m
left join {{ info_schema('groups') }} as g on g.name = m."group"
where m.access = 'public'
and (
g.unique_id is null
or (
(g.owner_name is null or trim(g.owner_name) = '')
and (g.owner_email is null or trim(g.owner_email) = '')
)
)
Команды
Проверки запускаются командами dbt check и dbt build.
| Команда | Поведение |
|---|---|
dbt check | Запускает все проверки. |
dbt check <name1> <name2> … | Запускает только указанные проверки. Неизвестное имя проверки вызывает ошибку; имя отключённой проверки принимается, но сама проверка пропускается. |
dbt build | Запускает все включённые проверки до компиляции моделей. Неудачная проверка останавливает запуск до компиляции или выполнения любой модели. Нарушения с уровнем warn выводятся в отчёте, и сборка продолжается. Для пропуска проверок используйте --skip-checks. |
Пропуск проверок при сборке
Чтобы пропустить все проверки, передайте команде dbt build флаг --skip-checks.
dbt build --skip-checks
Чтобы пропустить определённую проверку, задайте enabled: false в её блоке config в YAML-файле. Проверка по-прежнему будет присутствовать в манифесте, но не будет выполняться.
checks:
- name: all_models_have_descriptions
config:
enabled: false
Настройка +enabled: false в dbt_project.yml отключает проверку без уведомления — в выводе ничто не указывает на то, что проверки были пропущены. Успешное выполнение dbt build в CI не позволяет определить, отсутствуют ли проверки в проекте или все они отключены. Запуск dbt check <name> для отключённой проверки также завершается успешно, не выполняя проверку и не возвращая ошибку.
Использование селекторов с проверками
При работе с проверками --select и другие методы выбора определяют, какие ресурсы проекта проверять, а не какие проверки запускать.
Почему проверки работают именно так:
- Как правило, нет необходимости исключать проверки или запускать только часть из них. Проверки выполняются быстро. Проверки с уровнем error должны блокировать выполнение при нарушении правила; если правило носит информационный характер, задайте для него
warn. Если проверка больше не актуальна, отключите или удалите её. - Вам может потребоваться ограничить набор проверяемых ресурсов. Это позволяет постепенно внедрять проверки в существующий проект. Во время разработки запускайте
dbt build --select <the part of your DAG you're working on>, чтобы проверять только соответствующие ресурсы. В CI проверки выполняются только для изменённых ресурсов. - При разработке новой проверки можно запускать по одной проверке за раз и при необходимости выбирать ресурсы:
dbt check name_of_checkdbt check name_of_check --select <resources to check>
Также можно напрямую просмотреть результат любого запроса к info_schema: dbt show --inline "select * from {{ info_schema('...') }}". Например, чтобы изучить метаданные самих проверок, выполните dbt show --inline "select * from {{ info_schema('checks') }}".
Как работает selection_filter_on
По умолчанию dbt фильтрует результаты проверок по выбранным ресурсам, сопоставляя значения столбца unique_id в выводе. Если проверка не возвращает столбец unique_id, она выполняется для всего проекта.
Используйте selection_filter_on, если проверка возвращает строки с другими столбцами идентификаторов, по которым требуется фильтрация. Параметр принимает следующие значения:
- По умолчанию (не задано): Если запрос возвращает
unique_id, dbt сохраняет только строки, у которыхunique_idвходит в выборку. Если запрос не возвращаетunique_id, проверка выполняется для всего проекта. Это полезно для агрегатных проверок, например «в проекте есть хотя бы одна модель». none: Проверка всегда выполняется для всего проекта, игнорируя любые селекторы. Используйте это значение, чтобы явно задать проверку всего проекта.- Имя столбца или список имён столбцов: dbt сохраняет строку, если идентификатор хотя бы в одном из указанных столбцов входит в выборку. Каждый указанный столбец должен присутствовать в результате, иначе проверка завершится с ошибкой. Используйте этот вариант для проверок, которые возвращают связи между ресурсами (рёбра).
Например, следующая проверка возвращает child_unique_id вместо unique_id, поэтому необходимо задать selection_filter_on:
select child_unique_id, count(*) as source_parents
from {{ info_schema('edges') }}
where parent_unique_id like 'source.%'
group by child_unique_id
having count(*) > 1
checks:
- name: multiple_sources_joined
description: "Завершается неудачей, если какая-либо модель читает данные напрямую из нескольких источников."
config:
selection_filter_on: child_unique_id