Хранилища, адаптеры, хуки и операции
Один проект dbt работает на разных хранилищах — и умеет выполнять служебный SQL вокруг моделей.
Адаптер — плагин, переводящий dbt в диалект конкретного хранилища. Хуки и операции — способы выполнить произвольный SQL вокруг моделей или вручную.
Хранилища и адаптеры
Большая часть проекта dbt — стандартный SQL, поэтому переносимость высокая. Различия диалектов берёт на себя адаптер. Один и тот же проект с минимальными правками работает на разных хранилищах:
| Хранилище | Адаптер | Особенность |
| Snowflake | dbt-snowflake | Эластичные warehouse'ы, частый выбор для dbt |
| BigQuery | dbt-bigquery | Оплата за объём сканирования, партиции |
| Redshift | dbt-redshift | Дистрибуция и сортировка ключей |
| Postgres | dbt-postgres | Универсален, удобен для обучения и малых данных |
| ClickHouse | dbt-clickhouse | Колоночный, движки таблиц, своя специфика |
На сайте есть отдельные курсы по PostgreSQL и ClickHouse — там разобраны диалекты, на которые ложится dbt.
Хуки: SQL вокруг модели
Иногда нужно выполнить SQL до или после построения модели: выдать права на таблицу, собрать статистику, записать аудит-лог. Для этого есть pre-hook и post-hook:
{{ config(
materialized='table',
post_hook="grant select on {{ this }} to role analyst"
) }}
select ... from {{ ref('stg_orders') }}
Здесь после каждого построения модели dbt автоматически выдаёт права на чтение роли analyst. Хуки можно задавать и глобально в dbt_project.yml.
Операции: разовый SQL вне моделей
Когда нужно выполнить служебный макрос вручную (создать схему, почистить временные таблицы), используют run-operation:
-- macros/grant_all.sql
{% macro grant_all(role) %}
{% set sql %}
grant usage on schema analytics to role {{ role }}
{% endset %}
{% do run_query(sql) %}
{% endmacro %}
# Выполнить макрос как разовую операцию
dbt run-operation grant_all --args '{role: analyst}'
Как работает под капотом
Адаптер реализует набор «макросов диалекта»: как создать таблицу, как сделать merge, как назвать тип. Когда dbt компилирует модель, он подставляет реализацию из активного адаптера — поэтому {{ config(materialized='table') }} на Postgres и на Snowflake даёт корректный, но разный DDL. Хуки — это просто дополнительный SQL, который адаптер выполняет до/после основного запроса модели в той же транзакции (где хранилище это поддерживает). Операции выполняются вне контекста моделей через run_query.
Частые ошибки
- Использовать диалект-специфику без оглядки на адаптер. ClickHouse-движки или BigQuery-партиции не перенесутся на Postgres «как есть».
- Класть бизнес-логику в хуки. Хуки — для служебного SQL (гранты, аудит), а не для трансформаций.
- Путать хук и операцию. Хук привязан к модели и срабатывает при её сборке; операция запускается вручную через
run-operation.
Итоги
- Адаптер переводит dbt в диалект хранилища (Snowflake, BigQuery, Redshift, Postgres, ClickHouse) — проект переносим.
- Хуки (
pre/post) выполняют служебный SQL до/после модели; не для бизнес-логики. - Операции (
run-operation) запускают служебные макросы вручную, вне сборки моделей.