在Airflow DAG中生成多个任务以单独处理

时间:2019-02-25 16:10:05

标签: airflow apache-airflow-xcom

DAG的某些部分会生成列表,这些列表无法分解为单个任务,无法在下游单独处理。

这是一个伪示例:

def push(**kwargs):
    # """Pushes an XCom without a specific target"""
    for n in range(10):
        kwargs['ti'].xcom_push(key=f'vals', value=n)

def puller(**kwargs):
    ti = kwargs['ti']
    v1 = ti.xcom_pull(key='vals', task_ids='push')
    print(v1)

push = python_operator.PythonOperator(
    task_id='push',
    python_callable=push,
    provide_context=True
)

puller = python_operator.PythonOperator(
    task_id='puller',
    python_callable=puller,
    provide_context=True
)

似乎xcom_push仅使用最后一个值,而不生成列表。因此,我必须将push中的值加载到列表中,然后在pull中使用for循环分别处理每个项目。

我完全可以这样做,但是执行批处理作业似乎违反直觉。

我将如何让拔出器拉出push生成的10个任务之一?

1 个答案:

答案 0 :(得分:1)

在DAG运行之间,您不应该更改DAG的结构,因此,您的上拉器要么是一项任务,意味着要提取所有值,要么是10项任务,每个项目都希望提取其中一个值。

以下是使用xcom推送所有10个值的方法:

def push(**kwargs):
    # """Pushes an XCom without a specific target"""
    final_output = []
    for n in range(10):
        # doing work
        final_output.append(n)
    kwargs['ti'].xcom_push(key=f'vals', value=final_output)

push = python_operator.PythonOperator(
    task_id='push',
    python_callable=push,
    provide_context=True
)

然后您可以像这样拉动全部10个

def puller(**kwargs):
    ti = kwargs['ti']
    v1 = ti.xcom_pull(key='vals', task_ids='push')
    print(v1)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

puller = python_operator.PythonOperator(
    task_id='puller',
    python_callable=puller,
    provide_context=True
)

或者十项任务中的每一项都有一个值:

def puller(index=0, **kwargs):
    ti = kwargs['ti']
    v1 = ti.xcom_pull(key='vals', task_ids='push')[index]
    print(v1)

ten_ops = [python_operator.PythonOperator(
        task_id=f'puller_{n}',
        python_callable=puller,
        provide_context=True,
        op_kwargs={'index': n},
    ) for n in range(10)]

我希望这会有所帮助,除非我误解了这个问题。