Files
airflow-manual/05 - Основы построения DAG-файлов в Airflow.md
T
2025-10-18 23:25:42 +03:00

286 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Основы построения DAG-файлов в Airflow
В предыдущем занятии вы познакомились с пользовательским интерфейсом Airflow и, вероятно, задались вопросами: как создать свой собственный DAG? Где писать код? Какие именно инструкции использовать? В этом уроке вы получите ответы на все эти вопросы, создадите свой первый DAG, изучите базовую структуру кода и сможете загрузить его в систему для запуска и наблюдения за результатами.
# Как устроен код DAG-файла
Как вы уже знаете из предыдущих уроков, DAG представляет собой граф вычислений, состоящий из отдельных задач (tasks). На уровне кода DAG — это обычный Python-файл, который описывает все задачи в рамках пайплайна и определяет последовательность их выполнения.
Любой DAG-файл состоит из нескольких ключевых компонентов:
- Импорт необходимых модулей и библиотек
- Настройка параметров и инициализация объекта DAG
- Создание отдельных задач с помощью операторов
- Определение порядка выполнения задач
Порядок этих компонентов имеет значение, поскольку Airflow — это Python-библиотека, и обращение к еще не инициализированным объектам приведет к ошибкам выполнения.
Давайте рассмотрим простой пример DAG-файла и разберем его по частям.
![](_attachments/dag_file_structure.png)
*Пример структуры DAG-файла*
## Импорт необходимых модулей
Все начинается с подключения нужных библиотек и классов. Обязательно импортируйте класс DAG для создания графа вычислений. Затем подключайте операторы, которые понадобятся для описания ваших задач. Также могут потребоваться дополнительные функции или объекты для работы с данными.
```python
from datetime import datetime, timedelta
from airflow import DAG
from airflow.operators.bash import BashOperator
from airflow.utils.dates import days_ago
```
## Настройка параметров DAG
Следующим шагом идет объявление DAG с необходимыми параметрами:
В примере ниже создается DAG с идентификатором "sample_dag", который будет использовать общие параметры, определенные в словаре `default_args`. В данном случае, владелец DAG - это 'data_team', а дата начала выполнения - 1 января 2021 года.
```python
default_args = {
'start_date': datetime(2021, 1, 1),
'owner': 'data_team'
}
dag = DAG(
"sample_dag",
default_args=default_args,
schedule_interval=None,
)
```
Обратите внимание на словарь `default_args`. Это стандартная практика для хранения общих параметров, которые будут применяться ко всем задачам в DAG. Такой подход помогает избежать дублирования кода и делает его более читаемым. В примере мы указываем владельца пайплайна и дату начала его работы.
Ключевыми обязательными параметрами являются `owner` и `start_date`. Без них DAG не сможет быть корректно инициализирован и не появится в пользовательском интерфейсе Airflow. Остальные параметры являются опциональными и добавляются по мере необходимости.
Для изучения всех доступных параметров рекомендуем обращаться к официальной документации Airflow.
## Создание задач с помощью операторов
После настройки DAG следует этап создания задач. Для каждого шага обработки данных создается отдельная переменная с соответствующим оператором.
В Airflow существует множество готовых операторов для различных задач:
- `BashOperator` — для выполнения bash-команд
- `PythonOperator` — для запуска Python-функций
- Специализированные операторы для работы с популярными системами обработки данных (например, Apache Spark)
Каждая задача должна иметь уникальный идентификатор (`task_id`), который используется Airflow для отображения задачи в интерфейсе.
Пример создания простых задач:
В этом примере мы создаем две задачи с использованием BashOperator. Первая задача с идентификатором 'show_time' выводит текущее время, а вторая задача с идентификатором 'process_data' имитирует обработку данных с задержкой 3 секунды и возможностью повторного запуска при ошибках (до 2 раз).
```python
# Задача для вывода текущего времени
t1 = BashOperator(
task_id='show_time',
bash_command='date',
dag=dag
)
# Задача для имитации обработки с возможностью повторных попыток
t2 = BashOperator(
task_id='process_data',
bash_command='sleep 3',
retries=2,
dag=dag
)
```
## Определение последовательности выполнения
Завершающий этап — указание порядка выполнения задач. В Airflow для этого используются стрелочные операторы:
В приведенном примере задача с идентификатором 'process_data' будет запускаться только после успешного завершения задачи 'show_time'.
```python
t1 >> t2 # t2 запускается после завершения t1
```
Альтернативный синтаксис:
Этот синтаксис эквивалентен предыдущему примеру, просто записан в обратном порядке. Задача 'show_time' должна завершиться перед запуском задачи 'process_data'.
```python
t2 << t1 # t1 должна завершиться перед запуском t2
```
Можно также группировать задачи в списки для создания более сложных зависимостей:
В этом примере задачи 't2' и 't3' будут запускаться одновременно после завершения задачи 't1'. Затем задача 't4' запустится после завершения обеих задач 't2' и 't3'.
```python
t1 >> [t2, t3] # t2 и t3 запускаются одновременно после t1
[t2, t3] >> t4 # t4 запускается после завершения t2 и t3
```
Для сложных пайплайнов можно создавать цепочки любой сложности:
```python
t1 >> [t2, t3] >> t4 >> [t5, t6, t7] >> t8
```
## Полный пример DAG-файла
В этом полном примере мы создаем DAG с более подробной настройкой параметров. Обратите внимание на дополнительные параметры, такие как количество повторных попыток ('retries'), задержка между попытками ('retry_delay'), а также настройки уведомлений по электронной почте.
Вот как выглядит готовый DAG-файл в итоге:
```python
from datetime import datetime, timedelta
from airflow import DAG
from airflow.operators.bash import BashOperator
from airflow.utils.dates import days_ago
default_args = {
'owner': 'data_team',
'depends_on_past': False,
'start_date': days_ago(1),
'email': ['data@example.com'],
'email_on_failure': False,
'email_on_retry': False,
'retries': 2,
'retry_delay': timedelta(minutes=3),
}
dag = DAG(
"sample_dag",
default_args=default_args,
schedule_interval=None,
)
t1 = BashOperator(
task_id='show_time',
bash_command='date',
dag=dag
)
t2 = BashOperator(
task_id='process_data',
bash_command='sleep 3',
retries=2,
dag=dag
)
t1 >> t2
```
**Важное замечание**: код DAG-файла выполняется Airflow при каждом сканировании директории DAG. Поэтому в нем не следует размещать тяжелые вычисления, чтение больших файлов или запросы к базам данных. DAG-файл должен быть максимально легковесным. Сложные операции следует выносить в отдельные функции и вызывать их через соответствующие операторы.
💡 **Правило**: DAG-файл не должен содержать ресурсоемких операций, загрузки файлов или сложных вычислений.
# Создаем свой первый рабочий пайплайн
Теперь давайте создадим полноценный пайплайн для работы с реальными данными. В качестве примера мы будем использовать датасет с информацией о клиентах, который часто применяется в задачах анализа данных.
Наш пайплайн будет состоять из трех этапов:
1. Загрузка исходного датасета из интернета
2. Создание агрегированной таблицы по регионам и категориям
3. Сохранение результата в базу данных PostgreSQL
Вот полный код нашего DAG:
```python
import os
import datetime as dt
import pandas as pd
from airflow.models import DAG
from airflow.operators.python import PythonOperator
from airflow.operators.bash import BashOperator
from sqlalchemy import create_engine
# Базовые параметры DAG
args = {
'owner': 'airflow',
'start_date': dt.datetime(2020, 12, 23),
'retries': 1,
'retry_delay': dt.timedelta(minutes=1),
}
def download_titanic_dataset():
url = 'https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv'
df = pd.read_csv(url)
engine = create_engine('postgresql+psycopg2://jovyan:jovyan@localhost:5432/de')
df.to_sql('titanic', engine, index=False, if_exists='replace', schema='public')
def pivot_dataset():
engine = create_engine('postgresql+psycopg2://jovyan:jovyan@localhost:5432/de')
titanic_df = pd.read_sql('select * from public.titanic', con=engine)
df = titanic_df.pivot_table(
index=['Sex'],
columns=['Pclass'],
values='Name',
aggfunc='count'
).reset_index()
df.to_sql('titanic_pivot', engine, index=False, if_exists='replace', schema='public' )
dag = DAG(
dag_id='titanic_pivot',
schedule_interval=None,
default_args=args,
)
# Начальная задача для логирования
start = BashOperator(
task_id='start',
bash_command='echo "Начинаем выполнение пайплайна! "',
dag=dag,
)
# Загрузка исходного датасета
create_titanic_dataset = PythonOperator(
task_id='download_titanic_dataset',
python_callable=download_titanic_dataset,
dag=dag,
)
# Преобразование и сохранение сводной таблицы
pivot_titanic_dataset = PythonOperator(
task_id='pivot_dataset',
python_callable=pivot_dataset,
dag=dag,
)
# Последовательность выполнения
start >> create_titanic_dataset >> pivot_titanic_dataset
```
Этот код использует `PythonOperator` для выполнения функций работы с данными, что является стандартной практикой для задач обработки данных. В примере функция `load_customer_dataset` загружает данные из внешнего источника, а `aggregate_customer_dataset` создает агрегированную таблицу.
## Загрузка DAG в учебную среду
Для тестирования нашего DAG в учебной среде выполните следующие шаги:
1. Сохраните код в файл с расширением `.py` (например, `customer_analysis_dag.py`)
Для тестирования нашего DAG в учебной среде выполните следующие шаги:
1. Сохраните код в файл с расширением `.py` (например, `customer_analysis_dag.py`)
2. Найдите запущенный контейнер с учебной средой Airflow:
```bash
docker ps
```
3. Скопируйте файл в контейнер:
```bash
docker cp /путь/к/файлу/customer_analysis_dag.py [ID_КОНТЕЙНЕРА]:/lessons/dags/customer_analysis_dag.py
```
Например:
```bash
docker cp ~/Desktop/customer_analysis_dag.py 4dc4fbfedcf4:/lessons/dags/customer_analysis_dag.py
```
4. Подождите 30-60 секунд — Airflow автоматически обнаружит новый файл
5. Найдите ваш DAG в интерфейсе Airflow через строку поиска и запустите его
![Пример запуска DAG в интерфейсе Airflow](_attachments/dag_interface_example.png)
В этом уроке вы изучили основную структуру DAG-файлов, создали свой первый рабочий пайплайн, научились загружать его в учебную среду и запускать для получения результатов.