Больше времени на кодинг, меньше времени на ожидание: Осваиваем defer в dbt
Представьте себе — у вас огромный проект dbt, тысячи моделей работают, создавая полезные инсайты для ваших заинтересованных сторон. Вам поступает запрос — модель нужно переработать! "Нет проблем," думаете вы, "Я просто внесу изменения и протестирую их локально!" Вы смотрите на свою родословную и понимаете, что эта модель находится на многих уровнях глубоко, погребенная под длинной цепочкой таблиц и представлений.
"Хорошо," думаете вы дальше, "Я просто выполню dbt build -s +my_changed_model
, чтобы убедиться, что у меня все построено в моей dev-схеме, и я могу протестировать свои изменения". Вы запускаете команду. Ждете. Ждете еще. Берете кофе и полностью выходите из своего потока разработки dbt. Много времени и денег потрачено впустую, чтобы добраться до точки, где вы можете начать свою работу. Это не годится!
К счастью, функциональность defer в dbt п озволяет вам строить только то, что вам нужно, и ничего больше. Эта функция помогает разработчикам тратить меньше времени и денег на разработку, помогая быстрее выпускать надежные продукты данных. dbt Cloud предлагает нативную поддержку этого рабочего процесса в разработке, так что вы можете начать использовать defer без дополнительных затрат!
Defer to prod или предпочесть slog
Многое из магии dbt основывается на элегантности и простоте функции {{ ref() }}
, с помощью которой вы можете строить свой граф родословной, и как dbt может запускаться в разных средах — функции {{ ref() }}
динамически компилируются в зависимости от настроек вашей среды, так что вы можете запускать свой проект в разработке и производстве без изменения кода.
Вот как простая {{ ref() }}
будет компилироваться в разных средах:
- Raw Model Code
- Compiled in Dev
- Compiled in Prod
-- в models/my_model.sql
select * from {{ ref('model_a') }}
-- в target/compiled/models/my_model.sql
select * from analytics.dbt_dconnors.model_a
-- в target/compiled/models/my_model.sql
select * from analytics.analytics.model_a
Все это становится возможным благодаря manifest.json
в dbt, артефакту, который создается каждый раз, когда вы запускаете команду dbt, содержащему всеобъемлющий и энциклопедический справочник по всем аспектам вашего проекта. Каждому узлу присваивается unique_id
(например, model.my_project.my_model
), и манифест хранит все метаданные об этой модели в словаре, связанном с этим id. Это включает в себя местоположение в хранилище данных, которое возвращается, когда вы пишете {{ ref('my_model') }}
в SQL. Разные запуски вашего проекта в разных средах приводят к записи разных метаданных в манифест.
Давайте вернемся к гипотетической ситуации выше — что если мы воспользуемся производственными метаданными, чтобы читать данные из производства, чтобы мне не пришлось перестраивать все выше по потоку модели, которую я изменяю? Именно это и делает defer
! Когда вы предоставляете dbt производственную версию артефакта manifest.json
и передаете флаг --defer
в вашу команду dbt, dbt разрешит функции {{ ref() }}
для любого ресурса выше по потоку от выбранных вами моделей с использованием производственных метаданных — нет необходимости перестраивать то, что вам не нужно!
Давайте рассмотрим упрощенный пример — допустим, ваш проект выглядит так в производстве:
И вам поручено внести изменения в model_f
. Без defer вам нужно было бы как минимум выполнить dbt run -s +model_f
, чтобы убедиться, что все зависимости выше по потоку от model_f
присутствуют в вашей dev-схеме, чтобы вы могли начать запускать model_f
.* Вы только что потратили кучу времени и денег на дублирование ваших моделей, и теперь ваше хранилище выглядит так: