diff --git a/AGENTS.md b/AGENTS.md index 994938c..5dea9cd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,6 +11,9 @@ This repository contains an educational manual for Apache Airflow with runnable - `data/`: sample input data for exercises. - Note: `airflow-docker/AGENTS.md` adds extra, folder-specific guidance and takes precedence there. +## Practice Improvement Work +При переработке практических заданий, учебного поведения DAG или маршрута курса сначала прочитайте [план обновления практики](docs/specs/2026-09-28-practice-improvement-plan.md): согласованные решения, текущий этап и критерии его завершения. + ## Build, Test, and Development Commands Prerequisite: Docker + Docker Compose. - Build images: `cd airflow-docker && docker-compose build` diff --git a/airflow-docker/README.md b/airflow-docker/README.md index a08140f..444fc85 100644 --- a/airflow-docker/README.md +++ b/airflow-docker/README.md @@ -271,3 +271,7 @@ docker-compose up -d --- **Примечание**: Этот стенд предназначен исключительно для учебных целей. Для production использования требуется дополнительная настройка безопасности. + +## Для авторов курса + +[План обновления практики](../docs/specs/2026-09-28-practice-improvement-plan.md) — согласованный подход, найденные несогласованности, порядок доработки и проверки заданий. diff --git a/docs/specs/2026-09-28-practice-improvement-plan.md b/docs/specs/2026-09-28-practice-improvement-plan.md new file mode 100644 index 0000000..7bdbd41 --- /dev/null +++ b/docs/specs/2026-09-28-practice-improvement-plan.md @@ -0,0 +1,108 @@ +# План обновления практики по Airflow + +Дата: 2026-09-28. Подход согласован с автором курса. Реализация не начата; продолжение — первый незакрытый пункт в разделе «Порядок работы». + +Этот документ сохраняет решения и порядок дальнейшей работы. Текущие задания находятся в [educational-tasks.md](../../airflow-docker/educational-tasks.md), запуск стенда описан в [README](../../airflow-docker/README.md). + +## Цель и границы + +Стенд знакомит студентов с Apache Airflow и входит в [программу Data Engineering](https://de.dementev.space/). Перед ним студенты проходят Python, pandas, SQL и Docker. Самостоятельное построение цельных процессов обработки данных относится к последующим курсовым работам. + +Результат этого блока: студент умеет запустить готовый DAG, найти его граф и логи, внести небольшое изменение по образцу и объяснить наблюдаемое поведение. Практика остаётся набором небольших экспериментов с инструментом. + +Обновление сохраняет ознакомительный формат и версию Airflow 2.9.x. Основной маршрут выполняется на существующем стенде; внешние интеграции относятся к заданиям по желанию. Учебная имитация отдельных операций допустима, если описание и логи честно называют её имитацией. + +## Порядок работы + +Перед продолжением сверить чек-лист с текущими файлами и историей Git. Прочитать согласованные решения ниже, затем выполнить первый незавершённый этап. Локальные решения в этих границах принимать и записывать в рабочей таблице; противоречия с согласованной целью выносить на обсуждение. + +- [x] Зафиксировать подход и находки в этом документе; добавить ссылки из README стенда и AGENTS.md. +- [ ] **1. Разобрать все исходные задания.** Создать здесь рабочую таблицу с колонками: исходное задание (DAG/раздел и номер), изучаемая возможность, исходное состояние и зависимости, решение с обоснованием, место в будущем маршруте, наблюдаемый результат. Решения: оставить основным, разделить, перенести в дополнительные или переформулировать. Исходный набор — 25 заданий в `educational-tasks.md` на коммите `13e3102`; после переработки число упражнений может измениться. **Готово:** учтены 25 из 25 исходных заданий, у каждой части разделённого задания определена обязательность, а все зависимости основного маршрута обеспечены без выполнения дополнительных упражнений. Сопоставление с главами учебника объясняет выбор тем; новые темы добавляются только при выявленной необходимости для цели блока. +- [ ] **2. Проверить и исправить несогласованности.** Сверить каждую строку раздела «Найденные несогласованности и препятствия» с актуальным кодом. Для каждой записать итог: исправлено, не подтвердилось с объяснением или оставлено как явно описанный учебный сценарий. **Готово:** все находки разобраны; подтверждённые ошибки устранены, изменённое поведение проверено на версии стенда. Невыполненная проверка остаётся открытой. +- [ ] **3. Переработать показательный блок обработки ошибок.** Подготовить основной управляемый эксперимент с повтором, наблюдаемые результаты и отдельное усложнение по желанию. **Готово:** исходное состояние и возврат к нему описаны; воспроизведены успех после повтора и окончательная ошибка; логи, состояния задач и итог DAG Run совпадают с описанием. Этот блок служит образцом объёма и оформления остальных упражнений. +- [ ] **4. Переработать остальные блоки.** Применить выбранное распределение и образец к остальным заданиям. **Готово:** каждая строка рабочей таблицы ссылается на итоговое упражнение или содержит причину объединения; у каждого упражнения есть обязательность и проверяемый результат; подготовка и восстановление общих данных описаны там, где нужны. +- [ ] **5. Согласовать навигацию.** Обновить маршрут и оценку прогресса в `educational-tasks.md`, корневом README и README стенда. Сверить `dag-specifications.md` с итоговым содержанием. **Готово:** ссылки ведут к актуальным упражнениям; документы согласованно описывают порядок и условия завершения; устаревшие прототипы и необоснованные оценки времени удалены или исправлены. +- [ ] **6. Пройти маршрут двумя способами.** Выполнить только основную практику, затем дополнительные упражнения с переходами обратно к основной. **Готово:** обе последовательности пройдены в изолированном окружении; указанные результаты подтверждены в данных и UI; сохранены условия запусков, результаты и ограничения по правилам раздела «Как проверять результат доработки». + +По мере выполнения обновлять рабочую таблицу и чек-лист. У закрытого этапа указывать ссылку на коммит или запись о проверке. Если часть проверок недоступна, записать причину и продолжать независимую работу; соответствующий этап остаётся незавершённым. + +## Согласованные решения + +1. **Последовательность внутри блока.** Студент запускает исходный пример, меняет одну существенную настройку или часть графа и наблюдает результат. Изменения основных заданий внутри блока сохраняются. +2. **Ясное начало каждого блока.** Указаны исходный DAG, необходимые файлы, таблицы и настройки, а также изменения, которые остаются от предыдущей работы. Блок определяется учебным смыслом: загрузка CSV и последующая DQ-проверка могут объединять два DAG. +3. **Основная практика и задания по желанию.** Обязательность отделена от сложности. Дополнительные задания расположены в конце своего блока; их результаты не нужны для продолжения основной практики. Пропуск дополнительного задания не препятствует завершению блока. +4. **Разделение смешанных заданий.** Если одно упражнение объединяет знакомство с возможностью Airflow и значительное усложнение, оно разделяется. Например, TaskGroup и настройка настоящей отправки писем не должны быть одним обязательным заданием. +5. **Наблюдаемый результат.** У каждого задания есть раздел «Что должно получиться»: конкретное поведение в UI, сообщение в логах или результат в файле/таблице. Преднамеренная ошибка может быть правильным результатом упражнения. +6. **Управляемые учебные сценарии.** Основные примеры ветвления и повторных попыток позволяют гарантированно увидеть нужный случай. Случайность допустима в данных, если она не мешает наблюдать изучаемое поведение и проверять результат. +7. **Понятное завершение.** Основная практика даёт достаточное знакомство для перехода дальше по программе. Выполнение всех дополнительных упражнений не является скрытым условием прохождения курса. + +Дополнительное задание, меняющее общую таблицу или настройку, должно описывать возврат к состоянию, необходимому следующему блоку. Перенос задания в конец раздела сам по себе эту проблему не решает. Восстановление касается только объектов упражнения, без общего сброса стенда или чужих изменений. + +## Как оформлять задания + +Сохраняется один основной документ для студентов — `educational-tasks.md`. Не нужно дублировать инструкции в отдельном сборнике дополнительных упражнений. + +В начале блока: связь с главами учебника, необходимые исходные условия и короткий запуск готового примера. У задания: + +- пометка «Основная практика» или «По желанию»; сложность указывается отдельно; +- конкретное изменение, позволяющее познакомиться с одной возможностью Airflow; +- подсказка по необходимости; +- «Что должно получиться» с указанием места проверки; +- для экспериментов с ошибками — способ вызвать ошибку и вернуть нормальное поведение; +- при необходимости один короткий вопрос о причине наблюдаемого результата. + +Для ветвления и обработки ошибок проверяются статусы отдельных задач и всего DAG Run. Формулировка «всё зелёное» не подходит для сценария с ожидаемыми пропусками или ошибками. Проверка результата не должна требовать ожидания недельного расписания или неограниченного числа случайных запусков. + +## Предварительное распределение содержания + +Это начальная гипотеза для этапа 1. Окончательное распределение определяется рабочей таблицей после проверки зависимостей; правила прохождения находятся в разделе «Согласованные решения». + +| Блок | Основная практика | Возможное усложнение по желанию | +|---|---|---| +| Первый DAG | Запуск, граф, логи, добавление задачи по образцу, зависимости, знакомство с расписанием | Дополнительные эксперименты с ограничениями запусков | +| SQL и Connections | Выполнение SQL, смена подключения, наблюдение результата и ошибки подключения | Дополнительные отчёты и расширение модели данных | +| Файлы и преобразования | Проследить путь файла между задачами, изменить простое преобразование или проверку | Новые поля, графики, отчёты, обработка по отделам | +| CSV → PostgreSQL → DQ | Проследить загрузку, найти путь к файлу в XCom, добавить проверку, увидеть корректные и ошибочные данные | Расширение схемы с согласованным изменением загрузчика и DQ, общая сводка проверок | +| Пример ETL | Прочитать граф с параллельными задачами, найти промежуточные и итоговые результаты | Новый источник, расширенная аналитика, архивирование | +| Ветвление и Variables | Управляемо выбрать ветку, увидеть `skipped`, понять слияние веток | Третья ветка и полноценная обработка разных форматов | +| Ошибки и повторы | Вызвать ошибку, увидеть повтор и успешное завершение, найти причину в логах | Экспоненциальная задержка, разные исключения, эскалация | +| Пулы, TaskGroup и оповещения | Короткие отдельные эксперименты: ожидание слотов, группировка существующих задач, сообщение обработчика ошибки | Настоящая отправка писем и более сложные сценарии | + +Чтение и изменение XCom не должно зависеть от выполнения дополнительного задания по резервному копированию. Для знакомства с пулами достаточно готовых задач с наблюдаемой длительностью; написание механизма резервного копирования не является целью такого эксперимента. + +## Найденные несогласованности и препятствия + +Ниже зафиксированы результаты чтения кода и заданий. Это не отчёт о полном прохождении стенда: Docker, DAG и UI в рамках обсуждения не запускались. Семантика статусов и зависимостей сверялась с документацией Airflow 2.9.2. + +| Место | Наблюдение | Направление исправления | +|---|---|---| +| [SQL-задание](../../airflow-docker/educational-tasks.md), [sql_basic_dag.py](../../airflow-docker/dags/sql_basic_dag.py) | Совет заменить завершающий `TRUNCATE` на `DROP` не готовит уже существующую таблицу к вставке в новые колонки: выполнение может упасть раньше завершающей задачи. | Описать подготовку учебной таблицы до запуска и момент проверки данных до очистки. Согласовать имя задачи очистки с её действием. | +| [csv_to_postgres.py](../../airflow-docker/dags/csv_to_postgres.py) | Подсказка про добавление `status` упоминает генератор, DDL и COPY, но не итоговый `INSERT … SELECT`. | Провести поле через все этапы и проверять его значения в целевой таблице. | +| [csv_to_postgres_dq.py](../../airflow-docker/dags/csv_to_postgres_dq.py) | Строгая проверка схемы ожидает исходные четыре колонки и конфликтует с предыдущим расширением таблицы. | Согласовать порядок упражнений и исходное состояние DQ. Расширение схемы можно выполнять после знакомства с базовой загрузкой и проверками. | +| DQ-задание про Trigger Rules | После ошибки при стандартном `all_success` обещан `skipped`, хотя в описанном сценарии ожидается `upstream_failed`. | Исправить ожидаемые состояния и проверить их на стенде. | +| [error_handling_dag.py](../../airflow-docker/dags/error_handling_dag.py) | `chain` связывает два списка попарно: обработчик успеха зависит от одной рабочей задачи, обработчик ошибки — от другой. Комментарии описывают общий результат. | Согласовать граф с учебным сценарием; проверить варианты успеха и отказа каждой рабочей задачи, а также итог DAG Run. | +| DQ-сводка и [пример алертинга](../../09%20-%20Пулы,%20XCom,%20TaskGroup%20и%20алертинг%20в%20Airflow.md) | В исходном DQ используется `all_success`; риск возникает при предлагаемом в упражнении переходе на `all_done`. Успешная единственная завершающая задача с этим правилом может сделать DAG Run успешным при ошибке внутри. Пример письма также безусловно сообщает об успехе. | Явно определить желаемый итог и проверить согласованность статусов с сообщением. Отправку уведомления и успешность обработки рассматривать отдельно. | +| [data_processing_dag.py](../../airflow-docker/dags/data_processing_dag.py) | Загрузка в БД имитируется, но лог сообщает о загрузке. Transform читает исходные файлы, а не результаты Extract. | Честно назвать имитацию и согласовать показанный путь данных с фактическими входами задач. Полноценную загрузку ради этого примера добавлять необязательно. | +| Задание про пулы | Для пула из двух слотов и двух задач с потреблением два и один предлагается наблюдать «не более двух задач». Это не показывает существенное ограничение: эти две задачи одновременно не помещаются. | Описать ожидаемое ожидание одной задачи и дать достаточную длительность для наблюдения в UI. | +| Ветвление, повторы и дополнительные упражнения | Случайный выбор мешает гарантированно наблюдать нужный случай. Сравнение файлов двух взаимоисключающих веток не определяет, от каких запусков брать результаты. Некоторые задания требуют полей, добавленных раньше. | Задать управляемые сценарии, понятные входы и зависимости; исключить случайное использование результатов старого запуска. | + +Источники для технической сверки: [chain](https://airflow.apache.org/docs/apache-airflow/2.9.2/_api/airflow/models/baseoperator/index.html#airflow.models.baseoperator.chain), [статусы задач](https://airflow.apache.org/docs/apache-airflow/2.9.2/core-concepts/tasks.html#task-instances), [итог DAG Run](https://airflow.apache.org/docs/apache-airflow/2.9.2/core-concepts/dag-run.html#dag-run-status), [пулы](https://airflow.apache.org/docs/apache-airflow/2.9.2/administration-and-deployment/pools.html). + +## Как проверять результат доработки + +Результаты проверок сохранять в этом документе рядом с закрываемым этапом: проверенная версия/коммит, сценарий и исходное состояние, ожидаемый и фактический результат, способ проверки. Для длинных логов или снимков экрана достаточно ссылки на доступный артефакт. Версию Airflow сверять с фактическим окружением, а не только с тегом образа в Dockerfile. + +Проверки разделяются по уровню доказательств: + +- **Документы и исходники:** все 25 исходных заданий учтены, ссылки работают, имена файлов/задач/таблиц совпадают, обязательность и зависимости согласованы. +- **Стенд:** подтверждены версия Airflow и загрузка DAG без ошибок импорта; выполнены затронутые сценарии и проверены файлы/таблицы. Проверка синтаксиса Python не заменяет выполнение задач. +- **UI:** студент действительно может найти указанные состояния, логи, XCom, граф и настройки; показанные результаты совпадают с текстом. +- **Прохождение:** отдельно проверены основной маршрут и переходы после дополнительных заданий. Не выполненные проверки так и отмечаются; предполагаемое время не выдаётся за измеренное на студентах. + +Эксперименты с изменением данных выполняются в изолированном учебном окружении. Проверка не должна затрагивать другие работающие стенды или несвязанные изменения пользователя. + +## Почему выбран этот формат + +Одни метки сложности не разделяют смешанные упражнения и не объясняют условия продолжения. Полностью независимые задания увеличивают повторную подготовку. Отдельный сборник усложнений разрывает связь с исходным примером. Демонстрации без изменения кода дают меньше практики, а самостоятельный большой пайплайн дублирует цель последующих курсовых. + +Выбранный формат сохраняет практику изменения кода и позволяет переходить к следующему блоку после знакомства с нужными возможностями Airflow.