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

Обновление до dbt utils v1.0

Впервые dbt utils переходит на новую мажорную версию. Из публикации в блоге за прошлый месяц:

Пришло время официально закрепить то, что уже было негласным правилом: вы можете полагаться на dbt utils так же, как и на dbt v1, благодаря стабильным интерфейсам и последовательным, интуитивно понятным названиям.

Как и при переходе на dbt 1.0 в прошлом году, стандартизация и подготовка к будущему привели к некоторым несовместимым изменениям. Большинство изменений можно внести с помощью поиска и замены. Если вам нужна помощь, напишите на форуме сообщества или в канале #package-ecosystem в Slack.

Новые возможности​

  • get_single_value() — Простой способ получить одно значение из SQL-запроса вместо обращения к элементу [0][0] результата run_query.
  • safe_divide() — Возвращает null, когда знаменатель равен 0, вместо возникновения ошибки деления на ноль.
  • Новый тест not_empty_string — Более простая обёртка для проверки длины значений в столбце, чем использование expression_is_true.

Улучшения​

  • Многие тесты становятся более полезными, если запускать их для подгрупп строк таблицы. Например, может потребоваться проверить наличие свежих данных для каждого турникета, а не довольствоваться их наличием хотя бы для одного источника данных. Для этого добавьте в тесты новый аргумент group_by_columns. Подробнее об этом читайте в статье, написанной автором теста.
  • Благодаря добавлению в макрос star() аргумента quote_identifiers, включённого по умолчанию, теперь при необходимости можно отключить заключение идентификаторов в кавычки.
  • У теста recency теперь есть необязательный аргумент ignore_time_component, который можно использовать при проверке столбца с датами. Это позволяет избежать ложноположительных и ложноотрицательных результатов, вызванных временем суток, в которое запускается тест.

Исправления​

  • union() теперь включает и исключает столбцы без учёта регистра
  • slugify() добавляет в начало символ подчёркивания, если первый символ — цифра
  • Тест expression_is_true больше не выводит *, если сохранение не прошедших проверку строк не включено, что снижает затраты в BigQuery.

Несовместимые изменения​

Изменения в surrogate_key():​

  • surrogate_key() заменён на generate_surrogate_key(). Исходный макрос обрабатывал значения null и пустые строки одинаково, что могло приводить к созданию дублирующихся ключей. У generate_surrogate_key() этого недостатка нет. Сравните суррогатные ключи, вычисленные для этих столбцов:
Таблица со сравнением поведения surrogate_key и generate_surrogate_keyТаблица со сравнением поведения surrogate_key и generate_surrogate_key

Изменение способа вычисления суррогатных ключей, даже в лучшую сторону, может иметь существенные последствия для их дальнейшего использования (например, в снимках и инкрементальных моделях, которые используют этот столбец в качестве unique_key). Поэтому можно включить прежнее поведение, задав следующую переменную в проекте dbt:

#dbt_project.yml
vars:
surrogate_key_treat_nulls_as_empty_strings: true #turn on legacy behavior

Создавая новый макрос вместо изменения поведения старого, мы требуем, чтобы во всех проектах, использующих этот макрос, было принято явное решение о том, какой подход лучше подходит для их задач.

Мы рекомендуем текущим пользователям включить прежнее поведение, если только вы не уверены в одном из следующих условий:

  • ваши суррогатные ключи никогда не содержали null, или
  • ваши суррогатные ключи не используются в инкрементальных моделях, снимках и других артефактах, сохраняющих состояние, и поэтому могут быть без проблем пересозданы с новыми значениями.
Предупреждение для сопровождающих пакетов

Нельзя рассчитывать на какое-либо одно поведение, поскольку каждый проект может настроить его по-своему.

Функциональность, теперь встроенная в dbt v1:​


models:
- name: old_syntax
tests:
- dbt_utils.expression_is_true:
expression: "col_a + col_b = total"
#replace this...
condition: "created_at > '2018-12-31'"

- name: new_syntax
tests:
- dbt_utils.expression_is_true:
expression: "col_a + col_b = total"
# ...with this...
where: "created_at > '2018-12-31'"

Примечание — Из-за этого некоторые тесты могут получить одинаковые автоматически сгенерированные имена. Чтобы устранить проблему, можно задать собственное имя для теста.

  • Устаревшие тесты unique_where и not_null_where удалены, поскольку where теперь доступен во всех тестах на уровне ядра. Для перехода найдите и замените dbt_utils.unique_where на unique, а dbt_utils.not_null_where — на not_null.
  • dbt_utils.current_timestamp() заменён на dbt.current_timestamp().
    • Обратите внимание, что реализация dbt.current_timestamp() для Postgres и Snowflake отличается от прежней реализации в dbt_utils (подробности здесь). Если вы используете Postgres или Snowflake и вам нужно полностью сохранить прежнее поведение для обратной совместимости, используйте dbt.current_timestamp_backcompat(). Мы надеемся устранить это расхождение в одной из будущих версий dbt.
  • Все остальные кросс-платформенные макросы перенесены в пространство имён dbt; никаких изменений, кроме замены dbt_utils. на dbt., не требуется. Полный список приведён в документации по кросс-платформенным макросам.
    • В редакторе кода можно выполнить глобальный поиск и замену с помощью регулярного выражения: \{\{\s*dbt_utils\.(any_value|bool_or|cast_bool_to_text|concat|dateadd|datediff|date_trunc|escape_single_quotes|except|hash|intersect|last_day|length|listagg|position|replace|right|safe_cast|split_part|string_literal|type_bigint|type_float|type_int|type_numeric|type_string|type_timestamp|type_bigint|type_float|type_int|type_numeric|type_string|type_timestamp|except|intersect|concat|hash|length|position|replace|right|split_part|escape_single_quotes|string_literal|any_value|bool_or|listagg|cast_bool_to_text|safe_cast|dateadd|datediff|date_trunc|last_day) → {{ dbt.$1

Удаление материализации insert_by_period​

  • Материализация insert_by_period перенесена в репозиторий experimental-features. Чтобы продолжить её использование, добавьте следующее в файл packages.yml:
packages:
- git: https://github.com/dbt-labs/dbt-labs-experimental-features
subdirectory: insert_by_period
revision: XXXX #optional but highly recommended. Provide a full git sha hash, e.g. 1c0bfacc49551b2e67d8579cf8ed459d68546e00. If not provided, uses the current HEAD.

Удаление устаревшего поведения:​

  • safe_add() работает только со списком аргументов; используйте {{ dbt_utils.safe_add(['column_1', 'column_2']) }} вместо передачи отдельных аргументов {{ dbt_utils.safe_add('column_1', 'column_2') }}.
  • Реализован ряд давно обещанных изменений, связанных с удалением устаревших возможностей deduplicate():
    • Аргумент group_by заменён на partition_by.
    • Аргумент relation_alias удалён. Если нужен псевдоним, его можно передать непосредственно в аргументе relation.
    • Аргумент order_by теперь обязателен. Передайте постоянное значение, например 1, если вам неважно, каким образом удаляются дубликаты.
  • Устаревший аргумент table удалён из unpivot(). Вместо него используйте relation.

Устранение ошибок​

Ниже приведены распространённые сообщения об ошибках, с которыми можно столкнуться после обновления, и способы их устранения.

dict object has no attribute MACRO_NAME

Причина: Макрос с именем MACRO_NAME не существует. Скорее всего, это связано с тем, что макрос перенесён в пространство имён dbt (см. выше). Также причиной может быть то, что вы не выполнили dbt deps или допустили опечатку в имени макроса.

Решение: Для кросс-платформенных макросов замените dbt_utils.MACRO_NAME() на dbt.MACRO_NAME().

macro 'dbt_macro__generate_surrogate_key' takes not more than 1 argument(s)

Причина: generate_surrogate_key() требует один аргумент, содержащий список столбцов, а не набор отдельных аргументов.

Решение: Замените вызов на dbt_utils.generate_surrogate_key(['column_1', 'column_2']) — обратите внимание на квадратные скобки.

The dbt_utils.surrogate_key has been replaced by dbt_utils.generate_surrogate_key

Причина: Макрос surrogate_key() был заменён.

Решение:

  1. Решите, нужно ли включить обратную совместимость, как описано выше.
  2. Найдите и замените dbt_utils.surrogate_key на dbt_utils.generate_surrogate_key.
macro dbt_macro__test_expression_is_true takes no keyword argument condition

Причина: Аргумент condition удалён из теста expression_is_true, поскольку where теперь автоматически доступен для всех тестов.

Решение: Замените condition на where.

No materialization insert_by_period was found for adapter

Причина: Материализация insert_by_period перенесена в репозиторий экспериментальных возможностей (см. выше).

Решение: Установите пакет, как описано выше.

dbt found two tests with the name "XXX".

Причина: Замена condition на where в тесте expression_is_true, поскольку параметры конфигурации не входят в уникальное имя теста.

Решение: Задайте собственное имя для теста.

Нашли ошибку?

0
Loading