Раздел 26 · Data Engineering

Встроенные тесты: unique, not_null и другие

junior~15 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

В понедельник утром Отто пишет в чат: «Вчера в Центре 812 доставок? У нас столько в неделю не бывает». Ты час копаешься в данных и находишь причину: ночная выгрузка упала посередине, gonets_daily перезапустился и загрузил часть заказов второй раз. Модели честно всё посчитали, а дашборд показал удвоенные цифры. В уроке про качество данных такие проверки писали задачей в Airflow. В dbt они пишутся рядом с моделью, в том же YAML, где её описание.

ОТК на заводе

На заводе после каждого цеха стоит отдел технического контроля. Он не делает детали, он только смотрит: все ли болты на месте, нет ли брака. Нашёл брак, и партия дальше не едет, следующий цех её не получит.

Тесты dbt работают как такой отдел после каждой модели. Брак тоже не едет дальше: модели поверх непроверенной dbt пропускает.

Тест это запрос, который ищет плохие строки

Тест данных в dbt устроен просто: это SELECT, который ищет строки, нарушающие правило. Нашёл ноль строк, тест прошёл. Нашёл хотя бы одну, тест упал, и dbt пишет, сколько строк нашлось.

Самые частые правила уже написаны за тебя. Это generic-тесты, тесты-шаблоны, которые применяются к любой колонке одной строчкой в YAML. В dbt встроено четыре:

ТестЧто ищет
uniqueповторяющиеся значения колонки
not_nullпустые значения
accepted_valuesзначения не из списка
relationshipsзначения, которых нет в другой модели, «висячие» ссылки

Тесты в YAML

Тесты описывают в файле свойств рядом с моделями, под ключом data_tests у колонки:

# models/staging/_schema.yml
version: 2

models:
  - name: stg_orders
    columns:
      - name: order_id
        data_tests:
          - unique
          - not_null
      - name: status
        data_tests:
          - accepted_values:
              arguments:
                values: ["delivered", "cancelled"]
      - name: courier_id
        data_tests:
          - relationships:
              arguments:
                to: ref('stg_couriers')
                field: courier_id

У accepted_values и relationships есть параметры, они лежат под ключом arguments. В статьях и старых проектах ты увидишь две другие формы: ключ tests вместо data_tests и параметры прямо под именем теста, без arguments. dbt 1.12 их ещё понимает, но на вторую печатает предупреждение об устаревшем синтаксисе. Пиши по-новому.

relationships проверяет, что у каждого заказа курьер есть в stg_couriers. Пустой courier_id он не считает ошибкой: у 1051 заказа «Гонца» курьера нет, их отменили до назначения.

Каждый тест получает имя из типа, модели и колонки: unique_stg_orders_order_id. Запускает тесты команда dbt test, а dbt build собирает модели и тестирует их по порядку графа: сначала модель, потом её тесты, потом модели поверх неё.

урок из курса

Урок из курса «Data Engineering». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.