# Переход с оркестрации с учётом состояния на dbt State

Требуется вход | Оплата по использованию

dbt State расширяет возможности оркестрации с учётом состояния в нескольких ключевых аспектах:

* **Работает везде** — dbt State работает с dbt v1, dbt v2 и dbt platform, а также с внешними оркестраторами как в средах разработки, так и в средах развёртывания.
* **Более точное отслеживание актуальности данных** — dbt State отслеживает актуальность данных во всём DAG и автоматически передаёт сведения о ней через модели, материализованные как представления. В отличие от параметра `build_after` в оркестрации с учётом состояния, который выполняет сравнение относительно последнего успешного выполнения модели, параметр `lag_tolerance` в dbt State выполняет сравнение относительно актуальности исходных данных.
* **Расширенное обнаружение изменений** — dbt State может обнаруживать и игнорировать изменения файлов, которые не влияют на фактическую логику преобразований, например добавление комментария или удаление лишних пробелов.

Если вы использовали оркестрацию с учётом состояния до 1 июня 2026 года, вы можете продолжать ею пользоваться. После запуска бесплатного пробного периода dbt State он будет продлён сверх стандартных 30 дней. Если продление не применилось к вашей учётной записи, обратитесь к команде по работе с вашим аккаунтом. Подробную информацию об оплате после окончания пробного периода см. в разделе [Использование и стоимость dbt State](https://docs.getdbt.tech/docs/platform/billing/dbt-state-usage.md).

## Перенос конфигурации

Многие настройки dbt State покажутся знакомыми, если вы пользовались оркестрацией с учётом состояния, но есть одно существенное отличие: настройки `build_after` перенесены из блока `freshness` в новый блок `state`.

Чтобы перейти на dbt State, перенесите настройки из `freshness.build_after` в новый блок `state`. Полное соответствие настроек приведено в следующей таблице.

| Оркестрация с учётом состояния                                 | dbt State                                                                                                          | Примечания                                                                                                                                                                                                                                                                 |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `freshness.build_after.updates_on`                             | [`state.require_fresh_data_from`](https://docs.getdbt.tech/reference/resource-configs/require-fresh-data-from.md) | Те же варианты `any` и `all` с тем же поведением:<br />- `any` (по умолчанию): пересборка, когда у *любого* непосредственного родительского узла есть свежие данные<br />- `all`: пересборка, только когда у *всех* непосредственных родительских узлов есть свежие данные |
| `freshness.build_after.count` + `freshness.build_after.period` | [`state.lag_tolerance`](https://docs.getdbt.tech/reference/resource-configs/lag-tolerance.md)                     | Объединены в одно поле с сокращёнными значениями (например, `1800s`, `30m`, `12h`, `1d`, `2w`) или выражениями Jinja                                                                                                                                                       |

Обратная совместимость в dbt v2

В dbt v2 можно включить dbt State без предварительного обновления настроек проекта.

* Если `lag_tolerance` и `require_fresh_data_from` не заданы, dbt State использует существующие настройки `build_after` до тех пор, пока `build_after` не будет объявлен устаревшим.
* Если отсутствуют и `build_after`, и настройки `state`, dbt State использует [настройки по умолчанию](https://docs.getdbt.tech/reference/resource-configs/dbt-state-configs.md): `lag_tolerance: 45m` и `require_fresh_data_from: any`.

### Примеры

Эти настройки можно задать на уровне проекта в `dbt_project.yml` или на уровне модели в файле `.yml`.

**На уровне проекта:**

**До (оркестрация с учётом состояния)**

dbt\_project.yml

```yaml
models:
  +freshness:
    build_after:
      count: 1
      period: day
      updates_on: any
```

**После (dbt State)**

dbt\_project.yml

```yaml
models:
  +state:
    lag_tolerance: 1d
    require_fresh_data_from: any
```

**На уровне модели:**

**До (оркестрация с учётом состояния)**

models/my\_model.yml

```yaml
models:
  - name: my_model
    config:
      freshness:
        build_after:
          count: 1
          period: day
          updates_on: any
```

**После (dbt State)**

models/my\_model.yml

```yaml
models:
  - name: my_model
    config:
      state:
        lag_tolerance: 1d
        require_fresh_data_from: any
```

## Проверка перехода

Во время проверки можно использовать обе конфигурации параллельно. Оркестрация с учётом состояния считывает `freshness.build_after`, а dbt State — блок `state`, поэтому они не мешают друг другу. Убедившись, что всё работает правильно, удалите настройки `build_after`.

dbt\_project.yml

```yaml
models:
  +freshness:
    build_after:            # оркестрация с учётом состояния (удалите после перехода)
      count: 1
      period: day
      updates_on: any
  +state:                   # dbt State
    lag_tolerance: 1d
    require_fresh_data_from: any
```

## Известные отличия от оркестрации с учётом состояния

Оркестрация с учётом состояния и dbt State имеют несколько отличий:

* **Пересобирается больше моделей, чем ожидалось**: если после перехода вы заметили увеличение числа пересборок, чаще всего это связано со следующими причинами:

  * **Представления с `select *` из `ref()` или `source()`**: dbt State не может определить, каким столбцам соответствует `select *`, без запроса к схеме вышестоящего объекта, поэтому пересобирает такие представления, чтобы не рисковать повторным использованием устаревшего результата. Представления, использующие `select *` из CTE, используются повторно, поскольку dbt может определить столбцы из определения CTE. Подробнее см. в разделе [Представления с `select *`](https://docs.getdbt.tech/faqs/State/views-rebuilt.md#views-with-select).
  * **Недетерминированность SQL с шаблонами Jinja**: такие макросы, как `dbt_utils.get_relations_by_pattern` в сочетании с `dbt_utils.union_relations`, могут возвращать объекты базы данных в разном порядке при каждом запуске, что приводит к различиям в скомпилированном SQL. dbt State обнаруживает новый хеш и пересобирает модель. Если от этой модели зависят другие модели, они тоже пересобираются.
  * **Модели с внешними источниками в BigQuery**: модели, использующие внешние источники (например, Google Sheets), всегда пересобираются, поскольку BigQuery не предоставляет временные метки изменения внешних источников и dbt State не может определить свежесть данных.

  Чтобы избежать этого, настройте [`loaded_at_field`](https://docs.getdbt.tech/reference/resource-configs/freshness.md) или [`loaded_at_query`](https://docs.getdbt.tech/reference/resource-configs/freshness.md) в определении источника, указав поле с временной меткой, — это позволит dbt State запрашивать это поле напрямую для определения свежести данных, а не полагаться на метаданные хранилища.

  Подробнее о каждой причине и способах диагностики см. в разделе [Почему моя модель пересобирается, а не используется повторно?](https://docs.getdbt.tech/faqs/State/views-rebuilt.md).

* **`build_after` и `lag_tolerance`**: обе настройки снижают частоту запусков модели при частом обновлении вышестоящих данных, но работают по-разному:

  * `freshness.build_after` (например, `{count: 4, period: hour}`) пропускает модель, если не истёк заданный интервал *и* в вышестоящих источниках не появились новые данные с момента последнего запуска. Одно лишь изменение SQL не вызывает пересборку: должны выполняться оба условия.
  * `state.lag_tolerance` (например, `4h`) пропускает модель, если временная метка вышестоящих данных не превышает время последнего запуска модели как минимум на заданный интервал. В отличие от `build_after`, обнаруженное изменение SQL вызывает пересборку.

* **Нет обнаружения параллельных сборок**: в большинстве случаев dbt State обрабатывает общие узлы так же, как оркестрация с учётом состояния: если задание 1 собирает узел до начала задания 2, задание 2 видит, что модель уже собрана, и использует её повторно. Если задание 1 завершает сборку узла после начала задания 2, но до того, как задание 2 приступит к сборке этого узла, — задание 2 всё равно собирает его и тратит вычислительные ресурсы, чтобы повторно определить отсутствие новых данных. Однако если задание 2 начинает сборку того же снимка или инкрементальной модели до выполнения этого узла заданием 1, оба задания могут обнаружить одни и те же изменения в своих отдельных транзакциях и зафиксировать их, что может привести к дублированию записей или другим нарушениям целостности данных.

  Чтобы предотвратить повторные сборки, убедитесь, что задания с общими узлами не выполняются одновременно: настройте расписания заданий через [планировщик заданий dbt platform](https://docs.getdbt.tech/docs/deploy/job-scheduler.md) или внешний инструмент оркестрации (например, Airflow или Dagster) либо избегайте запусков вручную, которые пересекаются по времени.

* **Efficient Testing пока недоступно**: оркестрация с учётом состояния предлагает Efficient Testing (закрытая бета-версия); dbt State пока не поддерживает эту функцию.

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

* [О dbt State](https://docs.getdbt.tech/docs/deploy/dbt-state-about.md)
* [Настройка dbt State](https://docs.getdbt.tech/docs/deploy/dbt-state-setup.md)
* [Настройки dbt State](https://docs.getdbt.tech/reference/resource-configs/dbt-state-configs.md)
