# Определение конфигураций

Узнайте, как определять конфигурации для ваших ресурсов в dbt‑проекте

В зависимости от типа ресурса вы можете задавать конфигурации в dbt‑проекте, а также в установленном пакете, следующими способами:

(Версии dbt: v1.9 и новее)

1. Используя свойство [`config`](https://docs.getdbt.tech/reference/resource-properties/config.md) в файле `.yml` для поддерживаемых директорий ресурсов, таких как `models/`, `snapshots/`, `seeds/`, `analyses`, `tests/` и других.
2. Через файл [`dbt_project.yml`](https://docs.getdbt.tech/reference/dbt_project.yml.md), в соответствующем ключе ресурса (`models:`, `snapshots:`, `data_tests:` и так далее).

## Наследование конфигураций

Наиболее специфичная конфигурация всегда имеет приоритет. В общем случае это следует порядку, указанному выше: блок `config()` внутри файла → свойства, определённые в `.yml` файле → конфигурация, заданная в проектном файле.

Примечание: обобщённые data tests работают немного иначе с точки зрения специфичности. Подробнее см. [test configs](https://docs.getdbt.tech/reference/data-test-configs.md).

Внутри проектного файла конфигурации также применяются иерархически. Наиболее специфичная конфигурация всегда имеет приоритет. Например, конфигурации, применённые к поддиректории `marketing`, будут иметь приоритет над конфигурациями, применёнными ко всему проекту `jaffle_shop`. Чтобы применить конфигурацию к модели или директории моделей, определите [resource path](https://docs.getdbt.tech/reference/resource-configs/resource-path.md) в виде вложенных ключей словаря.

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

## Комбинирование конфигураций

Большинство конфигураций «перезаписываются» при применении по иерархии. Если доступно более конкретное значение, оно полностью заменяет менее конкретное. Обратите внимание, что некоторые конфигурации объединяются иначе:

* [`tags`](https://docs.getdbt.tech/reference/resource-configs/tags.md) суммируются. Если для модели настроены теги в `dbt_project.yml`, а в её файле `.sql` заданы дополнительные теги, итоговый набор будет включать их все.

* При использовании конфигурации [`freshness`](https://docs.getdbt.tech/reference/resource-configs/freshness.md) более конкретная пара «ключ — значение» заменяет менее конкретное значение с тем же ключом.

* [`pre-hook` и `post-hook`](https://docs.getdbt.tech/reference/resource-configs/pre-hook-post-hook.md) также суммируются.

* Словари [`meta`](https://docs.getdbt.tech/reference/resource-configs/meta.md) **объединяются поверхностно**: dbt объединяет только ключи верхнего уровня и не заглядывает во вложенные словари. Если один и тот же ключ верхнего уровня встречается на нескольких уровнях, более конкретное значение полностью заменяет менее конкретное — даже если это значение само является словарём. Ключи верхнего уровня, встречающиеся только на одном уровне, сохраняются. Например, если в `dbt_project.yml` задано:

  ```yaml
  +meta: {owner: "alice", dagster: {automation_condition: "eager"}}
  ```

  а в модели задано:

  ```yaml
  meta: {dagster: {asset_key: "my_key"}}
  ```

  результат будет следующим:

  ```yaml
  {owner: "alice", dagster: {asset_key: "my_key"}}
  ```

  `owner` сохраняется, поскольку встречается только на одном уровне. `dagster` встречается на обоих уровнях, поэтому более конкретное значение заменяет его целиком — а поскольку при объединении содержимое `dagster` не рассматривается, вложенный ключ `automation_condition` теряется. При глубоком (рекурсивном) объединении вложенные ключи, напротив, объединились бы, дав результат `dagster: {automation_condition: "eager", asset_key: "my_key"}`. В `meta` этого не происходит — вложенные словари заменяются, а не объединяются.

### Какая конфигурация имеет приоритет на разных уровнях

Для перезаписи и объединения конфигураций, наследуемых с нескольких уровней, действуют следующие общие правила:

* Конфигурации на уровне узла (более конкретные) перезаписывают конфигурации на уровне проекта (менее конкретные).
* Для источников конфигурации на уровне таблицы (более конкретные) перезаписывают конфигурации на уровне источника (менее конкретные).
* Конфигурация корневого проекта в `dbt_project.yml` перезаписывает конфигурацию в файлах пакетов. Это позволяет пользователям управлять поведением пакетов, устанавливаемых с помощью `dbt deps`, без необходимости напрямую редактировать код в файлах этих пакетов.

## Префикс `+`

dbt различает имя папки и конфигурацию, используя префикс `+` перед именем конфигурации. Префикс `+` используется **только** для конфигураций и применяется в файле `dbt_project.yml` в рамках соответствующего ключа ресурса. Он **не** применяется к:

* вызову макроса Jinja `config()` в файле ресурса
* свойству `config` в файле `.yml`.

Дополнительную информацию см. в разделе [Использование префикса `+`](https://docs.getdbt.tech/reference/resource-configs/plus-prefix.md).

## Пример

Ниже приведён пример, в котором для проекта определены и `sources`, и `models`:

models/jaffle\_shop.yml

```yml
version: 2

sources:
  - name: raw_jaffle_shop
    description: A replica of the postgres database used to power the jaffle_shop app.
    tables:
      - name: customers
        columns:
          - name: id
            description: Primary key of the table
            data_tests:
              - unique
              - not_null

      - name: orders
        columns:
          - name: id
            description: Primary key of the table
            data_tests:
              - unique
              - not_null

          - name: user_id
            description: Foreign key to customers

          - name: status
            data_tests:
              - accepted_values:
                  arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
                    values: ['placed', 'shipped', 'completed', 'return_pending', 'returned']


models:
  - name: stg_jaffle_shop__customers #  Must match the filename of a model -- including case sensitivity.
    config:
      tags: ['pii']
    columns:
      - name: customer_id
        data_tests:
          - unique
          - not_null

  - name: stg_jaffle_shop__orders
    config:
      materialized: view
    columns:
      - name: order_id
        data_tests:
          - unique
          - not_null
      - name: status
        data_tests:
          - accepted_values:
              arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
                values: ['placed', 'shipped', 'completed', 'return_pending', 'returned']
              config:
                severity: warn
```

## Связанная документация

Полный список всех поддерживаемых свойств и конфигураций, разбитый по типам ресурсов, можно найти здесь:

* Модели: [properties](https://docs.getdbt.tech/reference/model-properties.md) и [configs](https://docs.getdbt.tech/reference/model-configs.md)
* Источники: [properties](https://docs.getdbt.tech/reference/source-properties.md) и [configs](https://docs.getdbt.tech/reference/source-configs.md)
* Seed-данные: [properties](https://docs.getdbt.tech/reference/seed-properties.md) и [configs](https://docs.getdbt.tech/reference/seed-configs.md)
* Снимки (snapshots): [properties](https://docs.getdbt.tech/reference/snapshot-properties.md)
* Анализы: [properties](https://docs.getdbt.tech/reference/analysis-properties.md)
* Макросы: [properties](https://docs.getdbt.tech/reference/macro-properties.md)
* Экспозиции (exposures): [properties](https://docs.getdbt.tech/reference/exposure-properties.md)

## Часто задаваемые вопросы (FAQ)

Нужно ли называть мой файл \`.yml\`, содержащий тесты и описания, \`schema.yml\`?

Нет! Вы можете назвать этот файл как угодно (включая `whatever_you_want.yml`), при условии, что:

* Файл находится в вашем каталоге `models/`¹
* Файл имеет расширение `.yml`

Посмотрите [документацию](https://docs.getdbt.tech/reference/configs-and-properties.md) для получения дополнительной информации.

¹Если вы объявляете свойства для seeds, snapshots или macros, вы также можете разместить этот файл в соответствующем каталоге — `seeds/`, `snapshots/` и `macros/` соответственно.

Если я могу называть эти файлы как угодно, как мне их назвать?

Это зависит от вас! Вот несколько вариантов:

* Используйте существующую терминологию: `schema.yml` (хотя это может затруднить поиск нужного файла со временем)
* Используйте то же имя, что и у вашего каталога (при условии, что вы используете разумные имена для ваших каталогов)
* Если вы тестируете и документируете одну модель (или seed, snapshot, macro и т.д.) на файл, вы можете дать ему то же имя, что и у модели (или seed, snapshot, macro и т.д.)

Выберите то, что подходит вашей команде. У нас есть больше рекомендаций в нашем руководстве по [структурированию проектов dbt](https://docs.getdbt.tech/best-practices/how-we-structure/1-guide-overview.md).

Следует ли использовать отдельные файлы для объявления свойств ресурсов или один большой файл?

Это зависит от вас:

* Некоторые считают полезным иметь один файл на каждую модель (или источник / снимок / семя и т.д.)
* Другие считают полезным иметь один файл на каталог, документируя и тестируя несколько моделей в одном файле

Выберите то, что подходит вашей команде. У нас есть больше рекомендаций в нашем руководстве по [структурированию проектов dbt](https://docs.getdbt.tech/best-practices/how-we-structure/1-guide-overview.md).

Можно ли добавлять тесты и описания в SQL config-блоке?

dbt умеет задавать конфигурацию узлов в YAML-файлах, в дополнение к блокам `config()` и файлу `dbt_project.yml`. Однако обратное верно не всегда: есть некоторые вещи в `.yml` файлах, которые можно определить *только* там.

Некоторые свойства особенные, потому что:

* У них уникальный контекст рендеринга Jinja
* Они создают новые ресурсы проекта
* Они не имеют смысла как иерархическая конфигурация
* Это более старые свойства, которые еще не были переопределены как конфигурации

Эти свойства:

* [`description`](https://docs.getdbt.tech/reference/resource-properties/description.md)
* [`tests`](https://docs.getdbt.tech/reference/resource-properties/data-tests.md)
* [`docs`](https://docs.getdbt.tech/reference/resource-configs/docs.md)
* `columns`
* [`quote`](https://docs.getdbt.tech/reference/resource-properties/columns.md#quote)
* свойства [`source`](https://docs.getdbt.tech/reference/source-properties.md) (например, `loaded_at_field`, `freshness`)
* свойства [`exposure`](https://docs.getdbt.tech/reference/exposure-properties.md) (например, `type`, `maturity`)
* свойства [`macro`](https://docs.getdbt.tech/reference/resource-properties/arguments.md) (например, `arguments`)

Почему файлы YAML для моделей и источников всегда начинаются с \`version: 2\`?

Когда‑то структура этих файлов `.yml` была совсем другой (привет всем, кто пользовался dbt в те времена!). Добавление `version: 2` позволило нам сделать эту структуру более расширяемой.

Начиная с [dbt v1.5](<https://docs.getdbt.tech/docs/dbt-versions/dbt-upgrade/Older versions/upgrading-to-v1.5/.md#quick-hits>), ключ `version:` верхнего уровня необязателен во всех YAML-файлах ресурсов. Если он указан, поддерживается только значение `version: 2`.

Также, начиная с версии 1.5, и [`config-version: 2`](https://docs.getdbt.tech/reference/project-configs/config-version.md), и ключ верхнего уровня `version:` в файле `dbt_project.yml` являются необязательными.

В настоящее время ресурсные YAML‑файлы не требуют наличия этой настройки. Если она указана, мы поддерживаем только `version: 2`. Хотя мы не ожидаем в ближайшее время обновлять YAML‑файлы до `version: 3`, наличие этой конфигурации упростит для нас внедрение новых структур в будущем.

Могу ли я использовать расширение файла YAML?

Нет. В настоящее время dbt будет искать только файлы с расширением `.yml`. В будущих версиях dbt также будет искать файлы с расширением `.yaml`.

## Устранение распространённых ошибок

 Некорректная конфигурация теста в модели

Эта ошибка возникает, когда ваш файл `.yml` не соответствует структуре, ожидаемой dbt. Полное сообщение об ошибке может выглядеть так:

```text
* Invalid test config given in models/schema.yml near {'namee': 'event', ...}
  Invalid arguments passed to "UnparsedNodeUpdate" instance: 'name' is a required property, Additional properties are not allowed ('namee' was unexpected)
```

Хотя сообщение достаточно подробное, оно должно помочь определить источник проблемы. В данном случае поле `name` было по ошибке указано как `namee`. Чтобы исправить эту ошибку, убедитесь, что ваш `.yml` файл соответствует ожидаемой структуре, описанной в этом руководстве.

 Некорректный синтаксис файла schema.yml

Если ваш файл `.yml` не является корректным YAML, dbt покажет ошибку вида:

```text
Runtime Error
  Syntax error near line 6
  ------------------------------
  5  |   - name: events
  6  |     description; "A table containing clickstream events from the marketing website"
  7  |

  Raw Error:
  ------------------------------
  while scanning a simple key
    in "<unicode string>", line 6, column 5:
          description; "A table containing clickstream events from the marketing website"
          ^
```

Эта ошибка произошла из-за того, что после поля `description` по ошибке была использована точка с запятой (`;`) вместо двоеточия (`:`). Чтобы устранить подобные проблемы, найдите файл `.yml`, указанный в сообщении об ошибке, и исправьте все синтаксические ошибки в этом файле. В этом могут помочь онлайн-валидаторы YAML, однако будьте осторожны и не отправляйте конфиденциальную информацию в сторонние сервисы!
