# Отладка имен схем

[Назад к гайдам](https://docs.getdbt.tech/guides.md)

[Menu ]()



## Введение

Если модель использует [конфигурацию `schema`](https://docs.getdbt.tech/reference/resource-properties/schema.md), но создается в неожиданной схеме, вот несколько шагов для отладки этой проблемы. Полное объяснение пользовательских схем можно найти [здесь](https://docs.getdbt.tech/docs/build/custom-schemas.md).

Вы также можете следовать за видео:

## Поиск макроса с именем `generate_schema_name`

Выполните поиск файлов, чтобы проверить, есть ли у вас макрос с именем `generate_schema_name` в каталоге `macros` вашего проекта.

### У вас нет макроса с именем `generate_schema_name` в вашем проекте

Это означает, что вы используете реализацию макроса по умолчанию от dbt, как определено [здесь](https://github.com/dbt-labs/dbt-adapters/blob/60005a0a2bd33b61cb65a591bc1604b1b3fd25d5/dbt/include/global_project/macros/get_custom_name/get_custom_schema.sql)

```sql
{% 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 %}
```

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

### У вас есть макрос `generate_schema_name` в проекте, который вызывает другой макрос

Если ваш макрос `generate_schema_name` выглядит следующим образом:

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

В вашем проекте макрос `generate_schema_name` заменяется другим макросом — `generate_schema_name_for_env`. Как и в примере выше, этот макрос определён в глобальном проекте dbt, [здесь](https://github.com/dbt-labs/dbt/blob/main/crates/dbt-loader/src/dbt_macro_assets/dbt-adapters/macros/get_custom_name/get_custom_schema.sql).

```sql
{% macro generate_schema_name_for_env(custom_schema_name, node) -%}

    {%- set default_schema = target.schema -%}
    {%- if target.name == 'prod' and custom_schema_name is not none -%}

        {{ custom_schema_name | trim }}

    {%- else -%}

        {{ default_schema }}

    {%- endif -%}

{%- endmacro %}
```

### У вас есть макрос `generate_schema_name` с пользовательской логикой

Если это так — возможно, стоит обратиться к человеку, который добавил этот макрос в ваш проект, так как у него будет контекст — вы можете использовать [функцию blame на GitHub](https://docs.github.com/en/free-pro-team@latest/github/managing-files-in-a-repository/tracking-changes-in-a-file) для этого.

Во всех случаях уделите время, чтобы прочитать Jinja и попытаться следовать логике.

## Подтвердите вашу конфигурацию `schema`

Проверьте, используете ли вы [конфигурацию `schema`](https://docs.getdbt.tech/reference/resource-properties/schema.md) в вашей модели, либо через блок `{{ config() }}`, либо из `dbt_project.yml`. В обоих случаях dbt передает это значение как параметр `custom_schema_name` макроса `generate_schema_name`.

## Подтвердите ваши значения target

Большинство макросов `generate_schema_name` включают логику из [переменной `target`](https://docs.getdbt.tech/reference/dbt-jinja-functions/target.md), в частности `target.schema` и `target.name`. Используйте документацию [здесь](https://docs.getdbt.tech/reference/dbt-jinja-functions/target.md), чтобы помочь вам найти значения каждого ключа в этом словаре.

## Объедините все вместе

Теперь перечитайте логику вашего макроса `generate_schema_name` и мысленно подставьте ваши значения `customer_schema_name` и `target`.

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

Будьте внимательны. Снимки не следуют этому поведению, если задан параметр target\_schema. Чтобы в v1.9+ или dbt снимки учитывали окружение, удалите [конфигурацию target\_schema](https://docs.getdbt.tech/reference/resource-configs/target_schema.md) из своих снимков. Если вам по-прежнему нужна пользовательская схема для снимков, используйте вместо неё конфигурацию [`schema`](https://docs.getdbt.tech/reference/resource-configs/schema.md).

## Имена схем с префиксом

По умолчанию dbt объединяет `target.schema` и `custom_schema_name` по следующему шаблону: `{target.schema}_{custom_schema_name}`.

Например, если `target.schema` имеет значение `public`, а для модели задано `+schema: silver`, dbt создаёт модель в схеме `public_silver`, а не `silver`.

Это поведение предусмотрено намеренно. Включение `target.schema` помогает предотвратить ситуации, когда разработчики и задания непрерывной интеграции (CI) создают объекты в одной и той же схеме и перезаписывают объекты друг друга.

Если в рабочем окружении вы хотите использовать отдельные имена схем, такие как `silver` и `gold`, примените показанный ранее [шаблон `generate_schema_name_for_env`, учитывающий окружение](#you-have-a-generateschemaname-macro-in-a-project-that-calls-another-macro). Этот шаблон использует пользовательское имя схемы, когда `target.name` имеет значение `prod`, сохраняя при этом целевую схему в окружениях разработки и CI.

Макрос выглядит так:

```sql
{% macro generate_schema_name_for_env(custom_schema_name, node) -%}
    {%- set default_schema = target.schema -%}
    {%- if target.name == 'prod' and custom_schema_name is not none -%}
        {{ custom_schema_name | trim }}
    {%- else -%}
        {{ default_schema }}
    {%- endif -%}
{%- endmacro %}
```

Проверьте фактическое расположение объектов с помощью `dbt ls --output json` или запроса к каталогу вашего хранилища данных (`pg_views`, `information_schema.tables` или аналогичному).

## Настройте по мере необходимости

Теперь, когда вы понимаете, как генерируется схема модели, вы можете настроить ее по мере необходимости:

* Вы можете настроить логику в вашем макросе `generate_schema_name` (или добавить этот макрос в ваш проект, если у вас его еще нет, и настроить оттуда)
* Вы также можете настроить детали вашего `target` (например, изменить имя цели)

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