13 KiB
Проверка обновленной практики
Дата: 2026-09-28. Код примеров: коммит cf1b770; задания и навигация: d8dfe83. Проверка выполнена авторским прогоном по заданиям. Это проверка воспроизводимости инструкций; время и трудность прохождения на студентах не измерялись.
Окружение
Образ собран из Dockerfile стенда. Фактические версии внутри контейнера: Apache Airflow 2.9.2, Python 3.12.4, pandas 2.1.4, mimesis 15.1.0, PostgreSQL provider 5.11.1. Executor: LocalExecutor, PostgreSQL 16.
Использован отдельный Compose-проект airflow-manual-practice-check: собственные новые тома БД и копии dags/, data/. Порты перенесены на 18089, 15439, 15440. Для автоматизации включен Basic Auth API, parallelism=4, интервалы обнаружения файлов сокращены до 5 секунд. Перед запуском измененного DAG проверялся новый разбор файла и выдерживался интервал обновления сериализованного графа.
Изменения студента выполнялись только в копиях. Внутри блока они сохранялись. Вначале прошли исходные примеры, затем основной маршрут без дополнительных заданий. Дополнительные расширения проверены после него. Независимые блоки выполнялись одновременно; загрузчик и DQ шли последовательно.
Повторный docker compose run --rm airflow-init на существующих томах также завершился с кодом 0: учетная запись сохранена, подключение пересоздано.
Исходные примеры
Все девять DAG загрузились без Import Errors и завершились успешно. Для resource_management_dag заранее создан пул из двух слотов. У error_handling_dag режим по умолчанию дал ошибку первой попытки и успех второй. У ветвления выбранная ветка успешна, другая пропущена.
SQL оставил трех студентов, загрузчик создал 1000 заказов, DQ прошел. Файловый пример записал 100 строк. ETL создал шесть заказов с общей суммой 2105, шаг simulate_load сообщил об имитации.
Основной маршрут
| Упражнения | Действия и фактический результат |
|---|---|
| 1.1-1.3 | После добавления погоды четыре задачи, после BashOperator пять; note.txt содержит Airflow works. Расписание изменилось на 0 0 * * 1, ручной запуск прошел. |
| 2.1-2.2 | Создано отдельное подключение. Неверный Conn Id при нуле повторов: create_table=failed, следующие задачи upstream_failed. После восстановления и UPDATE: Alice 25, Bob 24, Charlie 21. Повторный полный запуск оставил три строки. |
| 3.1 | Порог High изменен на 80000. Проверены 100 строк и соответствие категории зарплате в CSV того же запуска. |
| 4.1-4.2 | Второй последовательный запуск загрузчика увеличил число заказов до 2000. Добавлена проверка суммы: корректные данные проходят; один отрицательный заказ дает check_positive_amount=failed, сводка upstream_failed, DAG Run failed. Повторный UPDATE восстановил успешный DQ. |
| 5.1 | Фильтр в Extract дал 4 заказа и сумму 2000 в результате Transform. После удаления фильтра снова 6 и 2105. |
| 6.1 | Режимы csv, json, xml, затем csv: выбор нужной ветки, отказ при неизвестном формате и успешное восстановление. XCom слияния относится к текущему запуску. |
| 7.1-7.3 | retry_once: две попытки и успех; переопределение retries=0: окончательный отказ. fail_first, fail_second, fail_both: обработчик ошибки успешен, обработчик успеха upstream_failed, DAG Run failed. Режим success и возврат к retry_once успешны. Добавлена запись в лог обработчика успеха. |
| 8.1 | Интервалы выполнения задач с весами 2 и 1 не пересекаются. После замены веса 2 на 1 интервалы пересекаются. |
| 8.2-8.3 | Добавлена метрика total_rows=50. После TaskGroup обновлены оба полных task_id, все четыре задачи успешны; XCom сохранил 20, 30 и 50. |
Основной маршрут завершен без дополнительных упражнений.
Дополнительные упражнения
| Упражнения | Действия и фактический результат |
|---|---|
| 1.A | Два ручных запуска с задержкой 30 секунд и max_active_runs=1: задачи второго начались после завершения первого. Затем задержка удалена, DAG выключен. |
| 2.A-2.B | Колонка email добавлена через ALTER до запуска. Три адреса заполнены, отчет содержит 3 студента и средний возраст 23.33; UPDATE из основной практики сохранен. |
| 3.A-3.C | Новые поля проверены, файл опытных сотрудников отделен от полного. Численность отделов в JSON дает 100; сборка трех файлов содержит те же 100 уникальных id. Отдел sales выполнился со второй попытки без дублей. |
| 4.A | При неверном порядке CSV/COPY получено invalid input syntax for type numeric: "NEW". После согласования порядка новые статусы попали в БД и прошел DQ. После удаления поля из кода и таблицы DQ снова успешен; положительная сумма продолжает проверяться. |
| 4.B-4.C | Создание таблицы заменено PostgresOperator, загрузка и DQ успешны. Неверный ожидаемый тип amount при all_success дал upstream_failed у следующих задач. С all_done они выполнились, но сводка и DAG Run остались failed. Возврат numeric и исходных trigger rules восстановил успешный DQ. |
| 5.A-5.C | Справочник продуктов не изменил 6 заказов и сумму 2105. Топ-3: 1200, 400, 300; средний заказ Alice 640. Неверный клиент вызвал отказ проверки и заблокировал архив. После восстановления появился один архив, побайтово равный результату. |
| 6.A-6.B | Третья ветка выбрана для review и неизвестного формата; csv/json продолжают работать. Чтение двух фиксированных файлов дало по 2 записи с суммой 30 в отдельных запусках. |
| 7.A | Три повтора дали четыре неуспешные попытки, после которых DAG Run остался failed. |
| 7.B | ConnectionError, ValueError и OSError вызвали callback после второй попытки; проверены task_id и текст причины. В обеих попытках восстановленного retry_once callback отказа отсутствует. |
| 8.A | После группировки добавлен BashOperator с чтением XCom; в Details видна команда echo 50, в Logs число 50 и успешный выход. |
| 8.B | Локальный SMTP принял одно письмо об отказе retry_task и одно об успехе DAG. При недоступном SMTP неуспешный запуск остался failed, успешный остался success. После отключения почтовых callbacks и возврата retry_once запуск успешен. |
Протокол запусков JSONL содержит 69 контрольных запусков и один диагностический запуск с неверным порядком CSV/COPY. Для каждого сохранены ожидаемый и фактический итог, состояния и число попыток задач, время начала и окончания. В первой строке указаны версии и SHA-256 итоговых DAG. Все ожидаемые состояния сошлись.
При выполнении уточнены инструкции: одинаковый порядок CSV/COPY; короткая задержка повтора в 3.C и 5.C; расположение Rendered Templates внутри Details; раскрытие TaskGroup нажатием на название со стрелкой. Сообщение callback оператора подтверждено в логе последней попытки. Команда docker compose logs airflow-scheduler его не показала. Отправка из callback DAG и ошибка его доставки найдены в /opt/airflow/logs/scheduler/latest/error_handling_dag.py.log.
Интерфейс и документы
Chromium: вход под учебной учетной записью, список девяти DAG, запуск кнопкой Trigger DAG, граф с четырьмя прямыми ребрами от рабочих задач к обработчикам. В Logs доступны две попытки; во второй видно Starting attempt 2 of 2 и сообщение об успехе. В XCom загрузчика найден путь к CSV; тот же CSV виден в Details, раздел Rendered Templates, у задачи загрузки. Часть пути там маскируется как ***; инструкция уточнена, имя файла сверено с XCom.
Снимки проверенных состояний: окончательный отказ, раскрытая TaskGroup, путь в Rendered Templates. Группа раскрыта нажатием на название со стрелкой, внутри видны обе задачи.
Markdown отрисован отдельно: восемь строк маршрута, 34 заголовка упражнений, рабочий переход к блоку ошибок. Проверены локальные ссылки и якоря в измененных документах, синтаксис девяти DAG и git diff --check.
После сохранения протокола изолированные контейнеры, браузер и два тестовых тома удалены. Остальные работающие сервисы не изменялись.
Границы проверки
Почтовый пример проверен на локальном SMTP-приемнике без отправки сообщений третьим лицам. Внешний провайдер, авторизация и TLS не проверялись: их параметры зависят от выбранного студентом сервера. Поведение Windows не проверялось на отдельной Windows-машине; опубликованные команды не используют синтаксис, специфичный для Bash.