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

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

Обновлен
Advanced
Menu

    Введение

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

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

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

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

    Блоки материализации позволяют 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 они должны выполнить. Вот некоторый псевдокод для фазы "настройки" материализации :

    -- Обратитесь к материализации таблицы (ссылка выше) для примера реального синтаксиса
    -- Этот код не будет работать и предназначен только для демонстрации
    {% 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

    Создайте свою материализацию , учитывая различные варианты существования , флаги материализации и т.д. Существует ряд функций адаптера и контекстных переменных, которые могут помочь вам в этом. Обязательно обратитесь к разделу 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