# Состояние проекта в dbt

dbt позволяет развертывать dbt с сохранением состояния. Артефакты доступны программно через [Discovery API](https://docs.getdbt.tech/docs/dbt-apis/discovery-querying.md) на платформе метаданных.

С внедрением конечной точки `environment` в Discovery API, мы ввели концепцию множественных состояний. Discovery API предоставляет единую конечную точку API, которая возвращает последнее состояние моделей, источников и других узлов в DAG.

Одна [среда развертывания](https://docs.getdbt.tech/docs/environments-in-dbt.md) должна представлять состояние конкретного проекта dbt в production.

В dbt можно запрашивать два состояния:

* **Примененное состояние** относится к тому, что существует в хранилище данных после успешного выполнения `dbt run`. Построение модели успешно завершено и теперь существует как таблица в хранилище.

* **Состояние определения** зависит от того, что существует в проекте, учитывая определенный в нем код (например, состояние манифеста), которое не обязательно было выполнено на платформе данных (возможно, это просто результат `dbt compile`).

## Состояние определения (логическое) vs. примененное состояние узлов dbt

В проекте dbt состояние *определения* узла представляет конфигурацию, трансформации и зависимости, определенные в файлах SQL и YAML. Оно фиксирует, как узел должен обрабатываться в отношении других узлов и таблиц в хранилище данных и может быть создано с помощью `dbt build`, `run`, `parse` или `compile`. Оно изменяется всякий раз, когда изменяется код проекта.

Применённое состояние включает информацию о выполнении — метаданные о том, как узел оказался в применённом состоянии. Поля в `executionInfo` отслеживают два связанных, но разных понятия:

| Понятие                           | Описание                                                                                                                                                                                                    | Поля                                                                                                                          |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Последняя попытка запуска         | Последний запуск независимо от результата (успех, ошибка или пропуск)                                                                                                                                       | `lastRunId`, `lastRunStatus`, `lastRunError`, `lastRunGeneratedAt`, `lastJobDefinitionId`                                     |
| Последняя успешная материализация | Последний запуск, в ходе которого узел был построен в хранилище данных.<br />Если запуск завершается с ошибкой, узел не перестраивается, поэтому эти поля сохраняют значения предыдущего успешного запуска. | `executeStartedAt`, `executeCompletedAt`, `executionTime`, `runGeneratedAt`, `lastSuccessRunId`, `lastSuccessJobDefinitionId` |

Например, если последний запуск модели завершается с ошибкой, значение `lastRunStatus` будет равно `error`, а `lastRunGeneratedAt` будет относиться к этому неудачному запуску, тогда как `executeCompletedAt` и `lastSuccessRunId` по-прежнему будут относиться к предыдущему запуску, в ходе которого модель была успешно материализована.

Вот как можно запросить и сравнить состояние определения модели и её применённое состояние с помощью Discovery API:

```graphql
query Compare($environmentId: Int!, $first: Int!) {
	environment(id: $environmentId) {
		definition {
			models(first: $first) {
				edges {
					node {
						name
						rawCode
					}
				}
			}
		}
		applied {
			models(first: $first) {
				edges {
					node {
						name
						rawCode 
						executionInfo {
							executeCompletedAt
						}
					}
				}
			}
		}
	}
}
```

Большинство случаев использования Discovery API будут отдавать предпочтение *примененному состоянию*, так как оно относится к тому, что было фактически выполнено и может быть проанализировано.

## Состояния, затронутые типом узла

Следующая таблица показывает состояния узлов dbt и как они затрагиваются Discovery API.

| Узел                                                                                         | Выполнен в DAG | Создан при выполнении | Существует в базе данных | Родословная            | Состояния                 |
| -------------------------------------------------------------------------------------------- | -------------- | --------------------- | ------------------------ | ---------------------- | ------------------------- |
| [Анализ](https://docs.getdbt.tech/docs/build/analyses.md)                                   | Нет            | Нет                   | Нет                      | Вверх по потоку        | Определение               |
| [Тест данных](https://docs.getdbt.tech/docs/build/data-tests.md)                            | Да             | Да                    | Нет                      | Вверх по потоку        | Примененное и определение |
| [Экспозиция](https://docs.getdbt.tech/docs/build/exposures.md)                              | Нет            | Нет                   | Нет                      | Вверх по потоку        | Определение               |
| [Группа](https://docs.getdbt.tech/docs/build/groups.md)                                     | Нет            | Нет                   | Нет                      | Вниз по потоку         | Определение               |
| [Макрос](https://docs.getdbt.tech/docs/build/jinja-macros.md)                               | Да             | Нет                   | Нет                      | Н/Д                    | Определение               |
| [Метрика](https://docs.getdbt.tech/docs/build/metrics-overview.md)                          | Нет            | Нет                   | Нет                      | Вверх и вниз по потоку | Определение               |
| [Модель](https://docs.getdbt.tech/docs/build/models.md)                                     | Да             | Да                    | Да                       | Вверх и вниз по потоку | Примененное и определение |
| [Сохраненные запросы](https://docs.getdbt.tech/docs/build/saved-queries.md)<br />(не в API) | Н/Д            | Н/Д                   | Н/Д                      | Н/Д                    | Н/Д                       |
| [Семя](https://docs.getdbt.tech/docs/build/seeds.md)                                        | Да             | Да                    | Да                       | Вниз по потоку         | Примененное и определение |
| [Семантическая модель](https://docs.getdbt.tech/docs/build/semantic-models.md)              | Нет            | Нет                   | Нет                      | Вверх и вниз по потоку | Определение               |
| [Снимок](https://docs.getdbt.tech/docs/build/snapshots.md)                                  | Да             | Да                    | Да                       | Вверх и вниз по потоку | Примененное и определение |
| [Источник](https://docs.getdbt.tech/docs/build/sources.md)                                  | Да             | Нет                   | Да                       | Вниз по потоку         | Примененное и определение |
| [Юнит-тесты](https://docs.getdbt.tech/docs/build/unit-tests.md)                             | Да             | Да                    | Нет                      | Вниз по потоку         | Определение               |

## Предостережения о обновлениях состояния/метаданных

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

Вот некоторые ограничения представления состояния в Discovery API:

* Пользователям необходим доступ к среде production по умолчанию, чтобы узнать актуальное состояние проекта.
* API получает определение из последнего манифеста, созданного в указанной среде развертывания, но зачастую этот манифест не отражает актуальное состояние кода проекта.
* Результаты компиляции кода могут быть устаревшими в зависимости от порядка шагов запуска dbt и сбоев при их выполнении.
* Информация в каталоге может быть устаревшей или неполной (в примененном состоянии) в зависимости от того, выполнялась ли команда `docs generate` и когда она выполнялась в последний раз.
* Результаты проверок актуальности источников могут быть устаревшими (в примененном состоянии) в зависимости от времени последнего запуска команды; при этом такие проверки не входят в `build`.
