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

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

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

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

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

Новые функции

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

Улучшения

  • Многие тесты более значимы, когда вы запускаете их для подгрупп таблицы. Например, вам может понадобиться проверить, что недавние данные существуют для каждого турникета, а не только для одного источника данных. Добавьте новый аргумент group_by_columns к вашим тестам, чтобы сделать это. Ознакомьтесь с этой статьей автора теста для получения дополнительной информации.
  • С добавлением аргумента quote_identifiers, включенного по умолчанию, в макросе star(), теперь вы можете отключить кавычки, если это необходимо.
  • Тест 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

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

#dbt_project.yml
vars:
surrogate_key_treat_nulls_as_empty_strings: true #включить поведение по умолчанию

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

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

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

Вы не можете предполагать одно поведение или другое, так как каждый проект может настроить свое поведение.

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


models:
- name: old_syntax
tests:
- dbt_utils.expression_is_true:
expression: "col_a + col_b = total"
#замените это...
condition: "created_at > '2018-12-31'"

- name: new_syntax
tests:
- dbt_utils.expression_is_true:
expression: "col_a + col_b = total"
# ...на это...
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 и вам необходимо полностью обратносovместимое поведение, используйте dbt.current_timestamp_backcompat(). Предполагается, что это расхождение будет устранено в одной из будущих версий dbt Core.
  • Все остальные кросс-базовые макросы были перемещены в пространство имён 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 #необязательно, но настоятельно рекомендуется. Укажите полный хеш git sha, например 1c0bfacc49551b2e67d8579cf8ed459d68546e00. Если не указано, используется текущий HEAD.

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

  • safe_add() работает только со списком аргументов; используйте {{ dbt_utils.safe_add(['column_1', 'column_2']) }} вместо varargs {{ 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() требует одного аргумента, содержащего список столбцов, а не набора varargs.

Решение: Измените на 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