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

Пользовательские схемы

По умолчанию все модели dbt собираются в схеме, указанной в вашем окружении (dbt) или в target профиля (dbt Core). Эта схема по умолчанию называется target schema.

Для проектов dbt с большим количеством моделей часто создают модели в нескольких схемах и группируют похожие модели вместе. Например, вы можете захотеть:

  • Группировать модели на основе бизнес-единицы, использующей модель, создавая такие схемы, как core, marketing, finance и support.
  • Скрыть промежуточные модели в схеме staging, и только представить модели, которые должны быть доступны для запроса конечным пользователем, в схеме analytics.

Для этого укажите пользовательскую схему. dbt генерирует имя схемы для модели, добавляя пользовательскую схему к целевой схеме. Например, <target_schema>_<custom_schema>.

Целевая схемаПользовательская схемаИтоговая схема
analytics_prodNoneanalytics_prod
alice_devNonealice_dev
dbt_cloud_pr_123_456Nonedbt_cloud_pr_123_456
analytics_prodmarketinganalytics_prod_marketing
alice_devmarketingalice_dev_marketing
dbt_cloud_pr_123_456marketingdbt_cloud_pr_123_456_marketing
Loading table...

Как использовать пользовательские схемы?​

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

  • применить эту конфигурацию к конкретной модели, используя блок конфигурации внутри модели
  • применить её к подкаталогу моделей, указав в файле dbt_project.yml
orders.sql
{{ config(schema='marketing') }}

select ...
dbt_project.yml
# модели в `models/marketing/ будут созданы в схеме "*_marketing"
models:
my_project:
marketing:
+schema: marketing

Понимание пользовательских схем​

При первом использовании пользовательских схем часто возникает недопонимание, что модель только использует новую конфигурацию schema; например, модель с конфигурацией schema: marketing будет создана в схеме marketing. Однако dbt помещает её в схему вида <target_schema>_marketing.

Есть веская причина для этого отклонения. Каждый пользователь dbt имеет свою собственную целевую схему для разработки (см. Управление средами). Если бы dbt игнорировал целевую схему и использовал только пользовательскую схему модели, каждый пользователь dbt создавал бы модели в одной и той же схеме и перезаписывал бы работу друг друга.

Комбинируя целевую схему и пользовательскую схему, dbt гарантирует, что объекты, которые он создает в вашем хранилище данных, не будут конфликтовать друг с другом.

Если вы предпочитаете использовать другую логику для генерации имени схемы, вы можете изменить способ, которым dbt генерирует имя схемы (см. ниже).

Как dbt генерирует имя схемы модели?​

dbt использует макрос по умолчанию под названием generate_schema_name, чтобы определить имя схемы, в которой должна быть создана модель.

Следующий код представляет логику макроса по умолчанию:

{% macro generate_schema_name(custom_schema_name, node) -%}

{%- set default_schema = target.schema -%}
{%- if custom_schema_name is none -%}

{{ default_schema }}

{%- else -%}

{{ default_schema }}_{{ custom_schema_name | trim }}

{%- endif -%}

{%- endmacro %}

💡 Используйте управление пробелами Jinja, чтобы упорядочить ваши макросы!

Когда вы изменяете макросы в вашем проекте, вы можете заметить лишние пробелы в вашем коде в папке target/compiled.

Вы можете удалить ненужные пробелы и строки с помощью управления пробелами Jinja, используя знак минус. Например, используйте {{- ... -}} или {%- ... %} вокруг определений ваших макросов (таких как {%- macro generate_schema_name(...) -%} ... {%- endmacro -%}).

Изменение способа генерации имени схемы в dbt​

Если в вашем проекте dbt есть пользовательский макрос под названием generate_schema_name, dbt будет использовать его вместо макроса по умолчанию. Это позволяет вам настроить генерацию имен в соответствии с вашими потребностями.

Чтобы настроить этот макрос, скопируйте пример кода из раздела Как dbt генерирует имя схемы модели в файл с именем macros/generate_schema_name.sql и внесите необходимые изменения.

Будьте осторожны. dbt будет игнорировать любые пользовательские макросы generate_schema_name, включенные в установленные пакеты.

 Предупреждение: Не заменяйте `default_schema` в макросе

Если вы изменяете способ генерации имен схем в dbt, не заменяйте просто {{ default_schema }}_{{ custom_schema_name | trim }} на {{ custom_schema_name | trim }} в макросе generate_schema_name.

Если вы удалите {{ default_schema }}, это приведет к тому, что разработчики будут перезаписывать модели друг друга, если они создадут свои собственные пользовательские схемы. Это также может вызвать проблемы во время разработки и непрерывной интеграции (CI).

❌ Следующий блок кода является примером того, как ваш код не должен выглядеть:

{% macro generate_schema_name(custom_schema_name, node) -%}

{%- set default_schema = target.schema -%}
{%- if custom_schema_name is none -%}

{{ default_schema }}

{%- else -%}
# Следующее неверно, так как опускается {{ default_schema }} перед {{ custom_schema_name | trim }}.
{{ custom_schema_name | trim }}

{%- endif -%}

{%- endmacro %}

Аргументы generate_schema_name​

АргументОписаниеПример
custom_schema_nameНастроенное значение schema в указанном узле, или none, если значение не указаноmarketing
nodenode, который в данный момент обрабатывается dbt{"name": "my_model", "resource_type": "model",...}
Loading table...

Контекст Jinja, доступный в generate_schema_name​

Если вы решите написать пользовательскую логику для генерации имени схемы, стоит отметить, что не все переменные и методы доступны вам при определении этой логики. Другими словами: макрос generate_schema_name компилируется с ограниченным контекстом Jinja.

Следующие методы контекста доступны в макросе generate_schema_name:

Контекст JinjaТипДоступен
targetПеременная✅
env_varПеременная✅
varПеременнаяОграничено, см. ниже
exceptionsМакрос✅
logМакрос✅
Другие макросы в вашем проектеМакрос✅
Другие макросы в ваших пакетахМакрос✅
Loading table...

Какие переменные доступны в generate_schema_name?​

Глобально-объявленные переменные и переменные, определенные в командной строке с помощью --vars, доступны в контексте generate_schema_name.

Управление различными поведениями в разных пакетах​

См. документацию по макросу dispatch: "Управление различными глобальными переопределениями в разных пакетах"

Встроенный альтернативный шаблон для генерации имен схем​

Распространённый вариант кастомизации — использовать пользовательскую схему в production, если она указана, а целевую схему применять только как запасной вариант, когда пользовательская схема не задана. В других окружениях, таких как development и CI, конфигурации пользовательских схем игнорируются, и вместо них всегда используется целевая схема.

Производственная среда (target.name == 'prod')

Целевая схемаПользовательская схемаИтоговая схема
analytics_prodNoneanalytics_prod
analytics_prodmarketingmarketing
Loading table...

Среда разработки/CI (target.name != 'prod')

Целевая схемаПользовательская схемаИтоговая схема
alice_devNonealice_dev
alice_devmarketingalice_dev
dbt_cloud_pr_123_456Nonedbt_cloud_pr_123_456
dbt_cloud_pr_123_456marketingdbt_cloud_pr_123_456
Loading table...

Подобно обычному макросу, этот подход гарантирует, что схемы из разных сред не будут конфликтовать.

dbt поставляется с макросом для этого случая — под названием generate_schema_name_for_env — который по умолчанию отключен. Чтобы его включить, добавьте пользовательский макрос generate_schema_name в ваш проект, содержащий следующий код:

macros/generate_schema_name.sql
-- поместите это в macros/generate_schema_name.sql

{% macro generate_schema_name(custom_schema_name, node) -%}
{{ generate_schema_name_for_env(custom_schema_name, node) }}
{%- endmacro %}

При использовании этого макроса вам нужно будет установить имя цели в вашем производственном задании на prod.

Управление средами​

В примерах макроса generate_schema_name, показанных в разделе встроенный альтернативный шаблон, переменная контекста target.name используется для изменения имени схемы, которое dbt генерирует для моделей. Если макрос generate_schema_name в вашем проекте использует переменную контекста target.name, вы должны убедиться, что ваши различные среды dbt настроены соответствующим образом. Хотя вы можете использовать любую схему именования, которую пожелаете, мы обычно рекомендуем:

  • dev — Ваше локальное окружение для разработки; настраивается в файле profiles.yml на вашем компьютере.
  • ci — Окружение непрерывной интеграции, которое запускается для pull request’ов в GitHub, GitLab и т. п.
  • prod — Продакшен‑развертывание вашего dbt‑проекта, например в dbt, Airflow или аналогичных системах.

Если ваши имена схем генерируются неправильно, дважды проверьте имя цели в соответствующей среде.

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

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

0
Loading