Макросы и пакет dbt_utils
Когда один и тот же кусок SQL повторяется в десяти моделях — пора писать макрос.
Макрос — именованный, параметризуемый фрагмент Jinja/SQL (аналог функции), который можно вызывать из любой модели для переиспользования логики.
Зачем макросы
DRY (Don't Repeat Yourself) применим и к SQL. Если в пяти моделях вы пишете один и тот же хитрый CASE для конвертации валют или одинаковую очистку телефона, любая правка означает пять одинаковых изменений. Макрос выносит логику в одно место.
Объявление макроса
-- macros/cents_to_dollars.sql
{% macro cents_to_dollars(column_name, decimals=2) %}
round({{ column_name }} / 100.0, {{ decimals }})
{% endmacro %}
Теперь вызов в любой модели:
select
order_id,
{{ cents_to_dollars('amount_cents') }} as amount_usd,
{{ cents_to_dollars('tax_cents', 4) }} as tax_usd
from {{ ref('stg_orders') }}
На этапе компиляции {{ cents_to_dollars('amount_cents') }} раскроется в round(amount_cents / 100.0, 2). Логика описана один раз, используется везде.
Пакет dbt_utils: готовые макросы
Сообщество собрало частые приёмы в пакет dbt_utils. Не нужно изобретать заново генерацию суррогатного ключа, сводную таблицу дат или проверку «звёздочкой».
select
{{ dbt_utils.generate_surrogate_key(['order_id', 'line_id']) }} as line_key,
*
from {{ ref('stg_order_lines') }}
| Макрос dbt_utils | Что делает |
generate_surrogate_key | Хэш-ключ из нескольких колонок |
star | SELECT всех колонок, кроме указанных |
date_spine | Сплошной календарь дат |
pivot | Разворот строк в колонки |
Подключение пакета
# packages.yml
packages:
- package: dbt-labs/dbt_utils
version: 1.1.1
# Установить пакеты, объявленные в packages.yml
dbt deps
Как работает под капотом
Макрос — это та же Jinja-функция, что и встроенные ref()/source(); просто вы пишете её сами. При компиляции dbt подставляет тело макроса с заданными аргументами в место вызова. Пакет — это набор чужих макросов (и иногда моделей), которые dbt deps скачивает в папку dbt_packages/, после чего они доступны через префикс пакета (dbt_utils.).
Частые ошибки
- Дублировать логику вместо макроса. Повтор одного и того же SQL в моделях — главный сигнал, что нужен макрос.
- Изобретать то, что есть в dbt_utils. Сперва проверьте, нет ли готового макроса.
- Забыть
dbt deps. Объявить пакет в packages.yml мало — его надо установить.
Итоги
- Макрос — функция для переиспользования SQL; объявляется в
macros/, вызывается из моделей. - Пакет dbt_utils даёт готовые макросы (surrogate_key, star, date_spine) — не изобретайте заново.
- Пакеты объявляют в packages.yml и ставят командой
dbt deps.