Витрина заказов «Гонца» стала таблицей, и дашборд Отто открывается быстро. Но каждую ночь dbt run пересобирает её с нуля: удаляет 41 тысячу строк и вставляет их заново, хотя за день прибавилось несколько сотен заказов. Пока это секунды. «Гонец» растёт, и через год в таблице будут миллионы строк, а ночная сборка начнёт упираться в утро. Хочется дописывать только то, что пришло с прошлого раза.
Дневник вместо пересказа
Представь дневник. Каждый вечер можно переписывать его с первой страницы целиком, добавляя сегодняшний день в конец. Это честно, но к концу года уходит вся ночь. А можно открыть дневник на последней записи, посмотреть её дату и дописать только то, что случилось после.
Обычная таблица в dbt переписывает дневник целиком. Инкрементальная модель дописывает с последней записи.
Инкрементальная модель
Инкрементальная модель это таблица с особым поведением:
- первый
dbt runстроит её целиком, как обычную таблицу; - следующие запуски выбирают только новые строки и дописывают их в уже готовую таблицу.
Какие строки считать новыми, решаешь ты. dbt не умеет угадывать, поэтому в модели пишут условие:
{{ config(materialized='incremental') }}
select order_id, zone_id, status, price_rub, created_at
from {{ ref('stg_orders') }}
{% if is_incremental() %}
where created_at > (select max(created_at) from {{ this }})
{% endif %}
Здесь две новые детали.
is_incremental() возвращает истину, только когда таблица модели уже существует и нужно дописывать. На первом запуске условия where в запросе нет, и строится вся таблица.
this это сама модель, её таблица в базе. Подзапрос select max(created_at) from {{ this }} спрашивает: какой самый поздний заказ уже лежит в таблице? Всё, что новее, и есть новые строки. Это та самая последняя запись в дневнике.
Конструкция {% if %} ... {% endif %} это Jinja, шаблонизатор, на котором написаны и двойные фигурные скобки. Подробно о нём в уроке про Jinja, а пока хватит одного правила: блок внутри попадёт в запрос, только если условие истинно.
урок из курса
Урок из курса «Data Engineering». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.