将下游任务添加到每个任务中,而不在Airflow 1.9的DAG中添加下游任务

时间:2018-07-30 17:13:58

标签: airflow

问题:我一直在尝试从DAG那里获取没有后续任务的任务的方法。

为什么需要:我正在为DAG建立“成功”通知。气流DAG具有一个on_success_callback参数,但是问题在于它是在每项任务成功之后触发的,而不仅仅是DAG。我看到其他人通过创建通知任务并将其附加到末尾来解决此问题。这种方法的问题在于,我们正在使用的许多DAG具有多个末端,并且有些是自动生成的。

确保所有末端都被手动抓住很繁琐。

我已经花了很多时间来寻找一种访问数据的方法,该数据是我需要构建的。

示例DAG设置

from airflow import DAG
from airflow.operators.dummy_operator import DummyOperator
from datetime import datetime

default_args = {
    'owner': 'airflow',
    'start_date': datetime(2018, 7, 29)}

dag = DAG(
    'append_to_end',
    description='append a tast to all tasks without downstream',
    default_args=default_args,
    schedule_interval='* * * * *',
    catchup=False)

task_1 = DummyOperator(dag=dag, task_id='task_1')
task_2 = DummyOperator(dag=dag, task_id='task_2')
task_3 = DummyOperator(dag=dag, task_id='task_3')

task_1 >> task_2
task_1 >> task_3

这将产生以下DAG:

DAG with two ending tasks

我要实现的目标是一种自动方法,可以将新任务包含到连接到所有端点的DAG中,如下图所示。

DAG with new task appended to both ending tasks

2 个答案:

答案 0 :(得分:1)

我知道这是一篇过时的文章,但是我有与上述文章类似的需求。 您可以在返回函数中添加不返回您的“ final_task” ID的语句,因此不会将其添加到get_leaf_task返回中,例如:

for task in leaf_tasks:
    task >> final_task

此外,您可以更改此部分:

get_leaf_tasks(dag) >> final_task

收件人:

<script>
$(document).ready(function () {
    $("#btnDownload").click(function () {        
        var apiUrl = "../api/DownloadExcel/ExportExcelFile?OriginalRequestNumber=";
        var originalReqIdentifier = $('#OriginalRequestNumber').val();          
        $.ajax({
            url: apiUrl + originalReqIdentifier,
            type: 'GET',
            dataType: 'json',
            success: function (data) {
                alert(data);
            },
            error: function (data) {
                window.location = apiUrl + originalReqIdentifier;
            }
        });
    });
});
</script>

由于它已经为您提供了任务实例列表,按位运算符“ >>”将为您执行循环。

答案 1 :(得分:0)

到目前为止,我需要做的是下面的代码:

def get_leaf_tasks(dag):
    return [task for task_id, task in dag.task_dict.items() if len(task.downstream_list) == 0]

leaf_tasks = get_leaf_tasks(dag)
final_task = DummyOperator(dag=dag, task_id='final_task')

for task in leaf_tasks:
    task >> final_task

它会产生我想要的结果,但是我对这种解决方案不满意的是,必须在创建get_leaf_tasks之前执行final_task,否则它将被包含在leaf_tasks中列表,我将不得不找到排除它的方法。

我可以将赋值包装在另一个函数中

def append_to_end(dag, task):
    leaf_tasks = get_leaf_tasks(dag)
    dag.add_task(task)

    for task in leaf_tasks:
        task >> final_task

final_task = DummyOperator(task_id='final_task')
append_to_end(dag, final_task)

这也不理想,因为呼叫者必须确保创建了final_task,但未分配DAG。