Data Pipelines with Apache Airflow, глава 2: Анатомия DAG
Главная мысль: DAG состоит из tasks. Каждая task запускает один operator. Порядок задают оператором >>. Airflow показывает статусы и логи, а упавшие tasks можно перезапустить через clear.

Пример из главы
Заголовок раздела «Пример из главы»Джон любит ракеты. Он хочет собирать картинки ближайших запусков в одну папку. Источник: бесплатный API Launch Library 2. Он отдаёт JSON со списком запусков, и у каждого есть ссылка на картинку.
План разбит на три tasks:
| Task | Operator | Что делает |
|---|---|---|
download_launches | BashOperator | Скачивает JSON через curl |
get_pictures | PythonOperator | Читает JSON и скачивает картинки |
notify | BashOperator | Печатает, сколько картинок скачано |
Правильных границ между tasks нет. Книга обещает вернуться к этому вопросу в других главах.
Из чего состоит DAG-файл
Заголовок раздела «Из чего состоит DAG-файл»- Импорты. В Airflow 3 класс
DAGберут изairflow.sdk. - Объект
DAGсdag_id,start_dateиschedule. - Tasks: объекты operators с уникальным
task_id. - Зависимости между tasks.
Три способа определить DAG:
| Способ | Плюс | Минус |
|---|---|---|
| Explicit: DAG передаётся в каждую task | Прямо видно, к какому DAG относится task | Много кода. Можно забыть аргумент |
Context manager (with DAG(...)) | Короче, меньше ошибок | Один DAG на блок. Новичкам синтаксис with может быть незнаком |
| Taskflow API | Современный стиль на декораторах | Разбирается в главе 6 |
Книга использует context manager.
Зависимости
Заголовок раздела «Зависимости»Порядок задают оператором >> (или <<):
download_launches >> get_pictures >> notify- Это Python-операторы побитового сдвига. Airflow переопределил их ради читаемости.
- Стрелка значит: следующая task стартует только после успеха предыдущей.
Task и operator
Заголовок раздела «Task и operator»- Operator делает одну единицу работы. Это шаблон:
BashOperatorзапускает команду,PythonOperatorвызывает функцию,EmailOperatorшлёт письмо. - Task это обёртка над operator. Она управляет запуском: состоянием, ошибками, зависимостями.
- В разговорах слова часто взаимозаменяют. Для пользователя это одно и то же.
- Все operators наследуются от
BaseOperator.
Как работает PythonOperator
Заголовок раздела «Как работает PythonOperator»- Вы пишете функцию. Книга называет её с подчёркиванием:
_get_pictures. - Передаёте её в
python_callable. - Всё, что функция печатает через
print, попадает в логи Airflow. task_idэто главный идентификатор task в логах, API и UI. Удобно называть переменную так же, какtask_id.
Запуск Airflow
Заголовок раздела «Запуск Airflow»Минимальный Airflow это пять компонентов: DAG processor, scheduler, API server, triggerer и база.
| Способ | Как | Когда |
|---|---|---|
| Python-окружение | pip install apache-airflow, затем airflow standalone | Быстрый старт. Команда создаёт базу и пользователя и запускает компоненты |
| Docker Compose | docker compose up в папке главы | Книга советует его. Окружение воспроизводимое |
- Ставьте
apache-airflow, а неairflow. Пакетairflowна PyPI это заглушка. - UI открывается на
localhost:8080. - В Docker файлы из
/tmpлежат внутри контейнера worker. Чтобы их увидеть, зайдите туда черезdocker exec.
Работа в UI
Заголовок раздела «Работа в UI»- Откройте список DAG. Включите DAG переключателем и нажмите
Trigger. - В
graph viewвидна структура DAG и цвета состояний. Этот вид удобен при разработке. - Нажмите на task и откройте
Logs. Там весь вывод. - В
grid viewкаждая колонка это один run. Каждая строка это одна task во времени.
Регулярный запуск
Заголовок раздела «Регулярный запуск»Чтобы не запускать вручную, задают schedule. Для примера: schedule="@daily", плюс start_date 14 дней назад и catchup=True. Тогда Airflow создаст 14 дневных runs за прошлое.
Подробно расписания разбираются в главе 3.

Причин много: сервис недоступен, ошибка в коде, нет сети, сломался диск.
- Упавшая task получает статус
failed. - Следующие tasks не запускаются. Их статус
upstream_failed, цвет оранжевый. - Причину ищут в логах. Там виден stack trace.
- Починили причину? Нажмите
Clear Task Instance. Можно очистить только эту task, а можно иUpstreamилиDownstream. - Перезапускать весь DAG не нужно. Успешные tasks остаются как есть.
- Автоматически сбои смягчают через
retries. Их разбирают в главе 6.
DAG versioning
Заголовок раздела «DAG versioning»Новая возможность Airflow 3.
- DAG processor замечает изменения кода и создаёт новую версию.
- В UI есть меню
Versions. Там видно старые версии кода и tasks. - В релизе 3.0.0 запуск всегда идёт по последней версии. Пока это скорее удобство для просмотра.
- Версии нужны как основа для более безопасных backfills и лучшей наблюдаемости.
- Работает через
DAG bundles. Локальная папка dags этоLocalDagBundle. Есть иGitDagBundle. Подробности в главе 17.
Пример кода
Заголовок раздела «Пример кода»Проверено на Airflow 3.4: DAG проходит airflow dags test.
Своя маленькая версия DAG с функцией на Python. Имена придуманы для примера.
import pendulumfrom airflow.providers.standard.operators.bash import BashOperatorfrom airflow.providers.standard.operators.python import PythonOperatorfrom airflow.sdk import DAG
def _count_words(): with open("/tmp/news.txt") as f: print(len(f.read().split()))
with DAG( dag_id="demo_news_words", start_date=pendulum.datetime(2025, 1, 1, tz="UTC"), schedule=None,): download = BashOperator( task_id="download", bash_command="curl -o /tmp/news.txt -L https://example.com", ) count = PythonOperator(task_id="count", python_callable=_count_words)
download >> countКлючевые термины
Заголовок раздела «Ключевые термины»| Термин | Значение |
|---|---|
dag_id | Имя DAG в UI |
task_id | Имя task внутри DAG |
BashOperator | Запускает команду shell |
PythonOperator | Вызывает Python-функцию (python_callable) |
>> | Задаёт порядок: левая task раньше правой |
Context manager | Блок with DAG(...), внутри которого tasks привязаны к DAG |
upstream_failed | Статус task, чья предыдущая task упала |
Clear | Сброс состояния task. Airflow запускает её заново |
DAG versioning | История версий структуры DAG (Airflow 3) |
DAG bundle | Источник DAG-кода: локальная папка или git |
Что это значит на практике
Заголовок раздела «Что это значит на практике»- Начинайте DAG с одного
dag_id, понятныхtask_idи явных зависимостей. - Не кладите тяжёлую логику внутрь DAG-файла. Держите функции короткими и выносите их в модули.
- При сбое сначала читайте логи task. Потом чините причину и делайте
clear, а не запускайте DAG целиком. - Помните про
upstream_failed: это не ошибка самой task, а следствие. - Для локальной разработки берите Docker Compose. Окружение будет одинаковым у всей команды.
- Ставьте
apache-airflow, неairflow.
Вопросы для самопроверки
Заголовок раздела «Вопросы для самопроверки»- В чём разница между task и operator?
- Какие три способа определить DAG? Какой выбрала книга и почему?
- Что значит статус
upstream_failedи что делать после починки причины? - Что даёт DAG versioning в Airflow 3 и чего он пока не делает?
Предыдущая: Знакомство с Airflow. Следующая: Расписания по времени.