# Задание 4: ошибки загрузки по дням, `dm.dq_errors_daily` Вы соберете дневную сводку ошибок загрузки. Ее итоги должны сохраниться и после того, как исходные сообщения будут удалены из хранилища. ## Подготовка - [«Хранилище и его слои»](../handbook/storage-layers.md); - [«Потоки Airflow и даги модельного времени»](../handbook/airflow-dags.md). ## Ошибки загрузки и их источники Если сообщение не удалось разобрать, стенд записывает его в таблицу ошибок. Такие строки дальше называются браком. Вы соберете сводку, по которой можно увидеть, каких ошибок стало больше и сколько строк забраковано. Источники сводки: - `ods.event_errors_dist`: ошибки разбора событий; - `ods.order_errors_dist`: ошибки разбора выгрузки заказов. В этих таблицах есть исходный текст сообщения и сведения о его доставке: они пригодятся при поиске причины ошибки. Представлений `_v` у таблиц ошибок нет, создавать их для задания не нужно. Чтение локальной таблицы `_rep` даст строки только одного шарда из двух, поэтому используйте `_dist`. ## Создание сводки В результате нужна одна строка на день загрузки, источник и класс ошибки. Например, ошибки `field_invalid` в заказах за один день загрузки попадут в одну строку с их количеством. Создайте пять объектов по [общим правилам ступени 1](README.md#создание-и-обновление-витрин): - основные таблицы `dm.dq_errors_daily_rep` и `dm.dq_errors_daily_dist`; - промежуточные таблицы `dm.dq_errors_daily_stage_rep` и `dm.dq_errors_daily_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#создание-и-обновление-витрин). ## Типичная ошибка Если заменить всю сводку новым расчетом, исчезнут итоги дней, за которые исходные строки уже удалены по `TTL`. Восстановить эти итоги неоткуда. ## Проверка результата Сопоставляйте строки по `load_date`, `source` и `error_class`. Проверяйте дни, оставшиеся хотя бы в одной таблице ошибок. Старые итоги, для которых исходные строки уже удалены по `TTL`, сверять не с чем. Посчитайте строки прямо в обеих таблицах ошибок и соедините результат с `dm.dq_errors_daily_v` через `FULL OUTER JOIN` по этим трем полям. Посчитайте строки, которые есть только с одной стороны или у которых различается `error_rows`. Расхождений должно быть ноль. Сумма `error_rows` по проверяемым дням равна общему числу строк в `ods.event_errors_dist` и `ods.order_errors_dist`. Если она примерно вдвое меньше, вероятная причина — чтение `_rep` вместо `_dist`. Если в источниках нет брака, витрина должна быть пустой. В этом случае расхождений тоже ноль и проверка успешна. ## Результат работы - [ ] у вас есть пять объектов витрины; промежуточная таблица объявлена через `AS` и использует ключ шардирования основной; - [ ] сводка включает ошибки событий и заказов из таблиц `_dist`; - [ ] ваш запрос пересобирает только дни, еще доступные в источниках, сохраняя более старые итоги; - [ ] проверка `dq_errors_daily` в `homework_check` прошла успешно; отсутствие брака тоже дает успешный результат; - [ ] витрина обновляется при запуске `dm_transform`.