Перейти к основному содержимому

Создание новых материализаций

Advanced
Menu

    Введение

    Материализации моделей, с которыми вы знакомы, такие как table, view и incremental, реализованы как макросы в пакете, который распространяется вместе с dbt. Вы можете ознакомиться с исходным кодом этих материализаций. Если вам нужно создать свои собственные материализации, чтение этих файлов — хорошее начало. Продолжайте читать ниже для глубокого погружения в материализации dbt.

    предупреждение

    Это продвинутая функция dbt. Дайте нам знать, если вам нужна помощь! Мы всегда рады пообщаться.

    Создание материализации

    Учитесь с помощью видео!
    Чтобы посмотреть видеоуроки по теме Materializations, перейдите в dbt Learn и ознакомьтесь с курсом Materializations fundamentals.

    Блоки materialization позволяют dbt загружать пользовательские материализации из пакетов. Эти блоки работают во многом так же, как и блоки macro, но с несколькими ключевыми отличиями. Материализации определяются следующим образом:

    {% materialization [имя материализации], ["указанный адаптер" | default] %}
    ...
    {% endmaterialization %}

    Материализациям можно дать имя, и они могут быть привязаны к конкретному адаптеру. dbt выберет материализацию, привязанную к текущему используемому адаптеру, если она существует, или вернется к default адаптеру. На практике это выглядит так:

    macros/my_materialization.sql
    {% materialization my_materialization_name, default %}
    -- кросс-адаптерная материализация... предположим, что Redshift не поддерживается
    {% endmaterialization %}


    {% materialization my_materialization_name, adapter='redshift' %}
    -- переопределение материализации для Redshift
    {% endmaterialization %}
    к сведению

    Способность dbt динамически выбирать правильную материализацию на основе активной базы данных называется множественной диспетчеризацией. Эта функция открывает целый мир возможностей для кросс-базовой совместимости — если вам это интересно, пожалуйста, дайте нам знать в Slack!

    Структура материализации

    Материализации отвечают за то, чтобы взять SQL-выражение модели dbt и превратить его в преобразованный набор данных в базе данных. Как правило, материализации имеют следующую структуру:

    1. Подготовить базу данных для новой модели
    2. Выполнить pre-hooks
    3. Выполнить весь SQL, необходимый для реализации требуемой материализации
    4. Выполнить post-model hooks
    5. Очистить базу данных при необходимости
    6. Обновить кэш Relation

    Каждая из этих задач объясняется в разделах ниже.

    Подготовка базы данных

    Материализации отвечают за создание новых таблиц или представлений в базе данных, а также за вставку, обновление и удаление данных в существующих таблицах. Соответственно, материализациям необходимо знать текущее состояние базы данных, чтобы точно определить, какой SQL им нужно выполнить. Ниже приведён пример псевдокода для этапа «настройки» материализации table:

    -- Обратитесь к материализации таблицы (ссылка выше) для примера реального синтаксиса
    -- Этот код не будет работать и предназначен только для демонстрации
    {% set existing = adapter.get_relation(this) %}
    {% if existing and existing.is_view %}
    {% do adapter.drop_relation(existing) %}
    {% endif %}

    В этом примере метод get_relation используется для получения состояния текущей выполняемой модели из базы данных. Если модель существует как представление, то представление удаляется, чтобы освободить место для таблицы, которая будет построена позже в материализации.

    Это упрощенный пример, и фаза настройки для материализации может стать довольно сложной! При создании материализации обязательно учитывайте состояние базы данных и любые предоставленные флаги (например, --full-refresh), чтобы гарантировать, что код материализации ведет себя правильно в различных сценариях.

    Запуск pre-hooks

    Pre- и post-hooks могут быть указаны для любой модели — убедитесь, что ваша материализация корректно работает с этими настройками. Две переменные, pre_hooks и post_hooks, автоматически внедряются в контекст материализации. Вызывайте эти хуки в нужное время с помощью:

    ...
    {{ run_hooks(pre_hooks) }}
    ....

    Выполнение SQL

    Создайте свою материализацию DML, учитывая различные варианты существования table, флаги материализации и т.д. Существует ряд функций адаптера и контекстных переменных, которые могут помочь вам в этом. Обязательно обратитесь к разделу Reference на этом сайте для полного списка доступных переменных и функций.

    Запуск post-hooks

    См. раздел выше о pre-hooks для получения дополнительной информации о запуске post-hooks.

    Очистка

    Фаза "очистки" материализации обычно переименовывает или удаляет отношения и фиксирует транзакцию, открытую на этапе "подготовки" выше. Например, материализация table выполняет следующий код очистки:

    {{ drop_relation_if_exists(backup_relation) }}

    Обязательно commit транзакцию на этапе cleanup материализации с помощью {{ adapter.commit() }}. Если вы не зафиксируете эту транзакцию, она будет отменена dbt, и преобразования, примененные в вашей материализации, будут отброшены.

    Обновление кеша Relation

    Материализации должны возвращать список отношений, которые они создали в конце выполнения. dbt использует этот список отношений для обновления кеша отношений, чтобы уменьшить количество запросов, выполняемых против information_schema базы данных. Если список отношений не возвращается, dbt выдаст предупреждение о депрекации и определит созданное отношение из настроенной базы данных, схемы и псевдонима модели.

    macros/my_view_materialization.sql
    {%- materialization my_view, default -%}

    {%- set target_relation = api.Relation.create(
    identifier=this.identifier, schema=this.schema, database=this.database,
    type='view') -%}

    -- ... настройка базы данных ...
    -- ... запуск pre-hooks...

    -- построение модели
    {% call statement('main') -%}
    {{ create_view_as(target_relation, sql) }}
    {%- endcall %}

    -- ... запуск post-hooks ...
    -- ... очистка базы данных...

    -- Возвращение отношений, созданных в этой материализации
    {{ return({'relations': [target_relation]}) }}

    {%- endmaterialization -%}

    Если материализация создает только одно отношение, то возвращение этого отношения в конце материализации достаточно для синхронизации кеша Relation dbt. Если материализация переименовывает или удаляет отношения, отличные от отношения, возвращаемого материализацией, то требуется дополнительная работа для поддержания кеша в синхронизации с базой данных.

    Чтобы явно удалить отношение из кеша, используйте adapter.drop_relation. Чтобы явно переименовать отношение в кеше, используйте adapter.rename_relation. Вызов этих методов предпочтительнее выполнения соответствующего SQL напрямую, так как они изменяют кеш по мере необходимости. Если вам нужно выполнить SQL для удаления или переименования отношений напрямую, используйте методы adapter.cache_dropped и adapter.cache_renamed для синхронизации кеша.

    Конфигурация материализации

    Материализации поддерживают пользовательскую конфигурацию. Вы, возможно, знакомы с некоторыми из этих конфигураций из материализаций, таких как unique_key в инкрементальных моделях или strategy в снимках.

    Указание параметров конфигурации

    Конфигурации материализации могут быть "необязательными" или "обязательными". Если пользователь не предоставляет обязательные конфигурации, dbt выдаст ошибку компиляции. Вы можете определить эти параметры конфигурации с помощью функций config.get и config.require.

    # необязательный
    config.get('optional_config_name', default="the default")
    # обязательный
    config.require('required_config_name')

    Для получения дополнительной информации о функции config dbt Jinja см. справочник config.

    Приоритет материализации

    dbt выберет макрос материализации в следующем порядке (нижний имеет приоритет):

    1. глобальный проект - по умолчанию
    2. глобальный проект - специфичный для плагина
    3. импортированный пакет - по умолчанию
    4. импортированный пакет - специфичный для плагина
    5. локальный проект - по умолчанию
    6. локальный проект - специфичный для плагина

    В каждом из указанных пространств поиска материализация может быть определена только один раз. Два разных импортированных пакета не могут предоставлять одну и ту же материализацию - будет выдана ошибка.

    Конкретные материализации можно выбрать, используя точечную нотацию при выборе материализации из контекста.

    Мы рекомендуем не переопределять имена материализаций напрямую, а вместо этого использовать префикс или суффикс, чтобы обозначить, что материализация изменяет поведение реализации по умолчанию (например, my_project_incremental).

    Нашли ошибку?

    0