Files
airflow-manual/docs/validation/2026-09-28-practice.md
T

13 KiB
Raw Blame History

Проверка обновленной практики

Дата: 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.