Материализации
Обзор
Материализации — это стратегии сохранения dbt-моделей в хранилище данных. В dbt встроено пять типов материализаций. Это:
- table
- view
- инкрементальный
- эфемерный
- материализованное представление
Вы также можете настраивать пользовательские материализации в dbt. Пользовательские материализации — это мощный способ расширить функциональность dbt и адаптировать его под ваши конкретные требования.
Настройка материализаций
По умолчанию dbt-модели материализуются как view. Модель можно настроить на использование другой материализации, указав параметр конфигурации materialized, как показано во вкладках ниже.
- Project file
- Model file
- Property file
# The following dbt_project.yml configures a project that looks like this:
# .
# └── models
# ├── csvs
# │ ├── employees.sql
# │ └── goals.sql
# └── events
# ├── stg_event_log.sql
# └── stg_event_sessions.sql
name: my_project
version: 1.0.0
config-version: 2
models:
my_project:
events:
# materialize all models in models/events as tables
+materialized: table
csvs:
# this is redundant, and does not need to be set
+materialized: view
В качестве альтернативы материализацию можно настраивать непосредственно внутри SQL-файлов модели. Это может быть удобно, если вы также задаёте конфигурации для [оптимизации производительности] для конкретных моделей (например, специфичные настройки Redshift или специфичные настройки BigQuery).
{{ config(materialized='table', sort='timestamp', dist='user_id') }}
select *
from ...
Материализации также можно настраивать в файле properties.yml модели. В следующем примере показан тип материализации table. Полный список типов материализаций см. в разделе materializations.
models:
- name: events
config:
materialized: table
Материализации
Представление
При использовании материализации view модель пересобирается как представление при каждом запуске с помощью оператора create view as.
- Плюсы: Не хранится дополнительных данных, представления поверх исходных данных всегда содержат самые актуальные записи.
- Минусы: Представления, выполняющие существенные преобразования или построенные поверх других представлений, медленно выполняются при запросах.
- Рекомендации:
- Обычно стоит начинать с представлений для моделей и переходить к другим материализациям только при появлении проблем с производительностью.
- Представления лучше всего подходят для моделей без сложных преобразований, например, для переименования или приведения типов столбцов.
Таблица
При использовании материализации table модель пересобирается как table при каждом запуске с помощью оператора create table as.
- Плюсы: Таблицы быстро обрабатываются при запросах.
- Минусы:
- Пересборка таблиц может занимать много времени, особенно при сложных преобразованиях.
- Новые записи в исходных данных не добавляются в таблицу автоматически.
- Рекомендации:
- Используйте материализацию
tableдля моделей, к которым обращаются BI-инструменты, чтобы обеспечить более быстрый отклик для конечных пользователей. - Также используйте
tableдля медленных преобразований, которые используются многими downstream-моделями.
- Используйте материализацию
Инкрементальный
Модели с материализацией incremental позволяют dbt вставлять или обновлять записи в таблице с момента последнего запуска этой модели.
- Плюсы: Можно существенно сократить время сборки, обрабатывая только новые записи.
- Минусы: Инкрементальные модели требуют дополнительной настройки и относятся к продвинутым сценариям использования dbt. Подробнее об их использовании читайте здесь.
- Рекомендации:
- Инкрементальные модели лучше всего подходят для данных событийного типа.
- Используйте инкрементальные модели, когда ваши
dbt runстановятся слишком медленными (то есть не начинайте сразу с инкрементальных моделей).
Эфемерный
Модели с материализацией ephemeral не создаются напрямую в базе данных. Вместо этого dbt подставляет код из ephemeral-модели в зависимые модели, используя общее табличное выражение (CTE). Вы можете управлять идентификатором этого CTE с помощью алиаса модели, однако dbt всегда добавляет к идентификатору модели префикс __dbt__cte__.
- Плюсы:
- Вы по-прежнему можете писать переиспользуемую логику.
- Ephemeral-модели помогают поддерживать чистоту data warehouse, уменьшая количество объектов (также рассмотрите разбиение моделей по нескольким схемам с помощью пользовательских схем).
- Минусы:
- Нельзя выполнять
selectнапрямую из этой модели. - Operations (например, макросы, вызываемые через
dbt run-operation) не могут делатьref()на ephemeral-узлы. - Чрезмерное использование ephemeral-материализации может усложнить отладку запросов.
- Ephemeral-материализация не поддерживает контракты моделей.
- Нельзя выполнять
- Рекомендации: Используйте материализацию
ephemeralдля:- очень лёгких преобразований на ранних этапах DAG,
- моделей, которые используются только в одной или двух downstream-моделях,
- и случаев, когда модель не требуется запрашивать напрямую.
Материализованное представление
Материализация materialized_view позволяет создавать и поддерживать материализованные представления в целевой базе данных.
Материализованные представления являются комбинацией представления и таблицы и подходят для сценариев, схожих с инкрементальными моделями.
- Плюсы:
- Материализованные представления объединяют производительность таблиц с актуальностью данных представлений.
- Материализованные представления работают во многом как инкрементальные материализации, однако обычно могут обновляться автоматически с заданной периодичностью (в зависимости от базы данных), без необходимости регулярного пакетного обновления через dbt, как это требуется для инкрементальных моделей.
dbt runдля материализованных представлений соответствует деплою кода, аналогично представлениям.
- Минусы:
- Поскольку материализованные представления являются более сложными объектами базы данных, платформы обычно предоставляют меньше вариантов конфигурации; подробности см. в документации вашей платформы.
- Материализованные представления поддерживаются не всеми платформами баз данных.
- Рекомендации:
- Рассмотрите использование материализованных представлений в случаях, когда инкрементальные модели подходят, но вы хотите, чтобы платформа данных сама управляла инкрементальной логикой и обновлением.
Мониторинг изменений конфигурации
Эта материализация использует конфигурацию on_configuration_change,
которая соответствует инкрементальной природе одноимённого объекта базы данных. Этот параметр указывает dbt пытаться применять изменения конфигурации напрямую к объекту,
когда это возможно, вместо полного пересоздания объекта для внедрения обновлённой конфигурации.
Например, при использовании dbt-postgres индексы могут быть удалены и созданы заново на материализованном представлении
без необходимости пересоздавать само представление.
Плановые обновления
В контексте команды dbt run материализованные представления следует рассматривать
аналогично обычным представлениям.
Например, команда dbt run требуется только в том случае, если возможно изменение
конфигурации или SQL; по сути, это действие деплоя.
В отличие от этого, для таблицы команда dbt run требуется в тех же сценариях и дополнительно тогда, когда данные в таблице нужно обновить.
Это также справедливо для инкрементальных моделей и snapshot-моделей, поскольку их базовые отношения — это таблицы.
В случае таблиц механизм планирования — это либо dbt, либо ваш локальный планировщик; встроенной функциональности для автоматического обновления данных в таблице не существует.
Однако большинство платформ (за исключением Postgres) предоставляют возможность настраивать автоматическое обновление материализованных представлений.
Поэтому материализованные представления работают аналогично инкрементальным моделям, но с преимуществом отсутствия необходимости запускать dbt для обновления данных.
Разумеется, это предполагает, что автоматическое обновление включено и настроено в модели.
dbt-snowflake не поддерживает материализованные представления; вместо этого используются Dynamic Tables. Подробнее см. в разделе специфичные настройки Snowflake.
Python-материализации
Python-модели поддерживают две материализации:
tableincremental
Инкрементальные Python-модели поддерживают те же инкрементальные стратегии, что и их SQL-аналоги. Конкретные поддерживаемые стратегии зависят от используемого адаптера.
Python-модели не могут быть материализованы как view или ephemeral. Python не поддерживается для типов ресурсов, отличных от моделей (например, тестов и snapshot-ов).
Для инкрементальных моделей, как и для SQL-моделей, необходимо фильтровать входные таблицы, оставляя только новые строки данных:
- Snowpark
- PySpark
import snowflake.snowpark.functions as F
def model(dbt, session):
dbt.config(materialized = "incremental")
df = dbt.ref("upstream_table")
if dbt.is_incremental:
# only new rows compared to max in current table
max_from_this = f"select max(updated_at) from {dbt.this}"
df = df.filter(df.updated_at >= session.sql(max_from_this).collect()[0][0])
# or only rows from the past 3 days
df = df.filter(df.updated_at >= F.dateadd("day", F.lit(-3), F.current_timestamp()))
...
return df
import pyspark.sql.functions as F
def model(dbt, session):
dbt.config(materialized = "incremental")
df = dbt.ref("upstream_table")
if dbt.is_incremental:
# only new rows compared to max in current table
max_from_this = f"select max(updated_at) from {dbt.this}"
df = df.filter(df.updated_at >= session.sql(max_from_this).collect()[0][0])
# or only rows from the past 3 days
df = df.filter(df.updated_at >= F.date_add(F.current_timestamp(), F.lit(-3)))
...
return df
Примечание: Инкрементальные модели поддерживаются в BigQuery/Dataproc для инкрементальной стратегии merge. Стратегия insert_overwrite пока не поддерживается.