Модели «Гонца» уже читают источники и ссылаются друг на друга. Все они пока представления: dbt по умолчанию делает из модели create view. Отто жалуется, что дашборд выручки по зонам открывается долго. Каждый раз, когда он обновляет страницу, база заново перебирает 41 тысячу заказов. Пора решить, во что превращать модель в базе. В dbt это решение называется материализацией.
Рецепт, кастрюля и соус
На кухне готовое блюдо можно держать тремя способами.
- Записать рецепт на карточку. Места не занимает, всегда по свежим продуктам, но каждый раз готовить заново и ждать.
- Сварить кастрюлю заранее и поставить в холодильник. Подаётся сразу, но пока стоит, может отстать от свежих продуктов, и под неё нужна полка.
- Соус, который отдельно не подают. Его не ставят в холодильник и не пишут в меню: он готовится внутри другого блюда, прямо в сковороде.
Это три основные материализации dbt.
Три способа
Материализация решает, что dbt создаст в базе из SELECT модели.
view. dbt выполняет create view и сохраняет в базе только запрос. Данные всегда свежие: каждый select из представления заново выполняет запрос по сырым таблицам. Место почти не занимает, собирается мгновенно, а читается медленно, если запрос тяжёлый. Это рецепт на карточке.
table. dbt выполняет create table as select и сохраняет результат. Читается быстро, но данные застывают на момент последнего dbt run: новые заказы появятся в таблице только после следующей сборки. Это кастрюля в холодильнике.
ephemeral. В базе не появляется ничего. Когда другая модель ссылается на эфемерную через ref(), dbt вставляет её запрос внутрь как CTE, в начало запроса через with. Это соус: удобно вынести шаг в отдельный файл, но таблица под него не нужна.
Есть и четвёртая, incremental, для больших таблиц, которые дописываются по кусочку. Ей посвящён следующий урок.
Как задать
Материализацию задают в самой модели, вызовом config() в начале файла:
{{ config(materialized='table') }}
select zone_id, sum(price_rub) as revenue_rub
from {{ ref('stg_orders') }}
where status = 'delivered'
group by zone_id
Или сразу для целой папки, в dbt_project.yml. В проекте «Гонца» так и сделано:
models:
gonets:
staging:
+materialized: view
intermediate:
+materialized: ephemeral
marts:
+materialized: table
Плюс перед ключом значит «это настройка, а не имя подпапки». Если заданы оба способа, побеждает config() в файле: настройка ближе к модели важнее. Остальные настройки dbt_project.yml разберём в уроке про конфигурацию проекта.
урок из курса
Урок из курса «Data Engineering». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.