# Задание 4: `dm.dq_errors_daily` **Чему учит:** считать брак по дню загрузки и сохранять сводку дольше исходных строк. ## Сначала прочитать - [«Хранилище и его слои»](../handbook/storage-layers.md); - [«Потоки Airflow и даги модельного времени»](../handbook/airflow-dags.md). ## Для чего нужна витрина Сводку открывают при росте брака в потоке: смотрят, каких ошибок стало больше и сколько строк забраковано. Причину конкретной ошибки исследуют в `ods.event_errors_dist` и `ods.order_errors_dist`, где есть сырой текст и координаты доставки. ## Что сделать Зерно — **день загрузки × источник × класс брака**. В источнике зерно — строка брака. Зерно новое, поэтому витрина хранится готовым агрегатом — см. [«Как принято на ступени 1»](README.md#как-принято-на-ступени-1). Создайте пять объектов: `dm.dq_errors_daily_rep` / `_dist`, донор `_stage_rep` / `_stage_dist` и публичное представление `dm.dq_errors_daily_v`. Ключ партиции — день загрузки. ### Состав колонок | Колонка | Тип | Значение | |---|---|---| | `load_date` | `Date` | День загрузки забракованной строки | | `source` | `LowCardinality(String)` | `event` или `order` | | `error_class` | `LowCardinality(String)` | Класс брака из таблицы ошибок | | `error_rows` | `UInt64` | Число забракованных строк | | `_load_id` | `String` | Идентификатор запуска, собравшего день | | `_load_ts` | `DateTime64(3, 'UTC')` | Время сборки | Вычислите `load_date` как `toDate(_load_ts)` из таблицы ошибок — это реальный день приема строки. Модельный день записан внутри исходной строки. Ее не удалось разобрать, поэтому надежно получить из нее день не получится. Служебная `_load_ts` витрины описывает сборку сводки; ее дата может отличаться от `load_date`. У событий и заказов свои классы брака. `source` входит в зерно, чтобы одинаковые имена классов с разным смыслом не объединялись в одну строку. ### Ритм пересборки Брак хранится месяц по `TTL`, сырые данные — трое суток. Сводка хранится бессрочно: итоги нужны и после удаления исходных строк. Получите список дней загрузки, еще имеющихся в источниках. Соберите их в донор и замените только эти партиции, сохранив остальные. В течение текущих суток ошибки еще поступают: пересчитайте этот день на следующем прогоне. ### Ключ шардирования Выберите ключ самостоятельно. Классов брака у событий и заказов вместе меньше десятка. Объясните, насколько существенен перекос при таком объеме. Ключ донора — тот же, что у цели (см. [«Как принято на ступени 1»](README.md#как-принято-на-ступени-1) и раздел «Раскладка по шардам» [справочника хранилища](../architecture/storage.md)). ## Источники: таблицы `_dist` Только это задание читает данные не через `_v`: брак нужен для диагностики приема и не входит в бизнес-модель. Публичных представлений у таблиц ошибок нет, создавать их для задания не нужно. Источники: - `ods.event_errors_dist` — ошибки разбора событий; - `ods.order_errors_dist` — ошибки разбора слепка заказов. Чтение локальной `_rep` даст строки одного шарда из двух: часть брака не попадет в сводку, хотя запрос выполнится без ошибки. ## Типичная ошибка Если заменить всю таблицу данными из нового донора, исчезнут итоги дней, истекших по `TTL` источника. Восстановить их неоткуда. ## Как проверить себя Деловой ключ — `source` и `error_class` внутри `load_date`. Проверяйте дни, оставшиеся хотя бы в одной таблице ошибок. Если дня за пределами `TTL` уже нет в источнике, это не ошибка: сверять его уже не с чем. Посчитайте строки прямо в обеих таблицах ошибок и соедините результат с `dm.dq_errors_daily_v` полным внешним соединением по ключу. Затем посчитайте строки, где ключ отсутствует с одной из сторон или различается `error_rows`. Расхождений должно быть ноль. Сумма `error_rows` по проверяемым дням равна общему числу строк в `ods.event_errors_dist` и `ods.order_errors_dist`. Если она примерно вдвое меньше, вероятная причина — чтение `_rep` вместо `_dist`. Если в источниках нет брака, витрина должна быть пустой. В этом случае расхождений тоже ноль и проверка успешна. ## Что должно получиться - [ ] у вас есть пять объектов витрины; донор объявлен через `AS` и использует ключ шардирования целевой таблицы; - [ ] сводка включает ошибки событий и заказов из таблиц `_dist`; - [ ] ваш запрос пересобирает только дни, еще доступные в источниках, сохраняя более старые итоги; - [ ] проверка `dq_errors_daily` в `homework_check` прошла успешно; отсутствие брака тоже дает успешный результат; - [ ] витрина обновляется при запуске `dm_transform`.