Обновление до 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()не имеет этого недостатка. Сравните суррогатные ключи, рассчитанные для этих столбцов:

Изменение метода расчета суррогатных ключей, даже в лучшую сторону, может иметь значительные последствия в последующих использованиях (например, в снимках и инкрементальных моделях, которые используют этот столбец в качестве unique_key). В результате, возможно включить поведение по умолчанию, установив следующую переменную в вашем проекте dbt:
#dbt_project.yml
vars:
surrogate_key_treat_nulls_as_empty_strings: true #включить поведение по умолчанию
Создавая новый макрос вместо обновления поведения старого, мы требуем от всех проектов, использующих этот макрос, принять явное решение о том, какой подход лучше для их контекста.
Наша рекомендация заключается в том, что существующие пользователи должны включить поведение по умолчанию, если вы не уверены, что:
- ваши суррогатные ключи никогда не содержали null-значений, или
- ваши суррогатные ключи не используются для инкрементальных моделей, снимков или других артефактов с состоянием и могут быть пересчитаны с новыми значениями без проблем.
Вы не можете предполагать одно поведение или другое, так как каждый проект может настроить свое поведение.
Функциональность, которая теперь встроена в dbt Core:
- Тест
expression_is_trueбольше не имеет отдельного аргументаcondition. Вместо него используйтеwhere, который теперь нативно доступен для всех тестов:
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() был заменен.
Решение:
- Решите, нужно ли вам включить обратную совместимость как описано выше.
- Найдите и замените
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, так как конфигурации не являются частью уникального имени теста.
Решение: Определите пользовательское имя для вашего теста.