Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
BranchPythonOperator之后的气流任务未正确失败和成功_Python_Airflow - Fatal编程技术网

BranchPythonOperator之后的气流任务未正确失败和成功

BranchPythonOperator之后的气流任务未正确失败和成功,python,airflow,Python,Airflow,在我的DAG中,我有一些任务应该只在周六运行。因此,我使用BranchPythonOperator在星期六的任务和Dummy任务之间进行分支。之后,我加入这两个分支,并希望运行其他任务 工作流如下所示: 在这里,我将dummy3的触发规则设置为“一次成功”,一切正常 我遇到的问题是,BranchPythonOperator的上游出现故障: BranchPythonOperator和分支正确地具有状态'upstream\u failed',但是加入分支的任务变为'skipped',因此整个工作

在我的DAG中,我有一些任务应该只在周六运行。因此,我使用BranchPythonOperator在星期六的任务和Dummy任务之间进行分支。之后,我加入这两个分支,并希望运行其他任务

工作流如下所示:
在这里,我将dummy3的触发规则设置为“一次成功”,一切正常

我遇到的问题是,BranchPythonOperator的上游出现故障:
BranchPythonOperator和分支正确地具有状态
'upstream\u failed'
,但是加入分支的任务变为
'skipped'
,因此整个工作流显示
'success'

我尝试使用
'all_success'
作为触发规则,如果某个操作失败,整个工作流将失败,但如果没有任何操作失败,dummy3将被跳过

我还尝试了
'all_done'
作为触发规则,如果没有失败,它会正常工作,但是如果有什么失败,dummy3仍然会被执行

我的测试代码如下所示:

from datetime import datetime, date
from airflow import DAG
from airflow.operators.python_operator import BranchPythonOperator, PythonOperator
from airflow.operators.dummy_operator import DummyOperator

dag = DAG('test_branches',
          description='Test branches',
          catchup=False,
          schedule_interval='0 0 * * *',
          start_date=datetime(2018, 8, 1))


def python1():
    raise Exception('Test failure')
    # print 'Test success'


dummy1 = PythonOperator(
    task_id='python1',
    python_callable=python1,
    dag=dag
)


dummy2 = DummyOperator(
    task_id='dummy2',
    dag=dag
)


dummy3 = DummyOperator(
    task_id='dummy3',
    dag=dag,
    trigger_rule='one_success'
)


def is_saturday():
    if date.today().weekday() == 6:
        return 'dummy2'
    else:
        return 'today_is_not_saturday'


branch_on_saturday = BranchPythonOperator(
    task_id='branch_on_saturday',
    python_callable=is_saturday,
    dag=dag)


not_saturday = DummyOperator(
    task_id='today_is_not_saturday',
    dag=dag
)

dummy1 >> branch_on_saturday >> dummy2 >> dummy3
branch_on_saturday >> not_saturday >> dummy3
编辑 我刚刚想出了一个难看的解决办法:
dummy4表示我实际需要运行的任务,dummy5只是一个虚拟任务。
dummy3仍然有触发规则
“一次成功”

现在,如果没有上游故障,dummy3和dummy4将运行;如果当天不是星期六,dummy5将“运行”;如果当天是星期六,dummy5将被跳过,这意味着DAG在这两种情况下都标记为成功。
如果上游出现故障,则跳过dummy3和dummy4,将dummy5标记为
“上游\u失败”
,并将DAG标记为失败


此解决方案使我的DAG可以按我所希望的方式运行,但我仍然希望使用一种没有任何复杂解决方案的解决方案。

您可以使用的一种解决方案是将DAG的第二部分放入子DAG中,就像我在下面演示示例的代码中所做的那样:

它按预期工作,并且可以说比您的解决方案更干净,因为您没有任何额外的子级虚拟操作符。但是,您丢失了平面结构,现在必须放大子DAG以查看内部结构的细节


一个更一般的观察:在对DAG进行实验后,我得出结论,气流需要一个类似JoinOperator的东西来取代Dummy3操作符。让我解释一下。您描述的行为来自这样一个事实,即DAG的成功仅基于最后一个操作符成功(或跳过!)

以下以«成功»状态结尾的DAG是支持上述声明的MWE

def python1():
    raise Exception('Test failure')

dummy1 = PythonOperator(
    task_id='python1',
    python_callable=python1,
    dag=dag
)

dummy2 = DummyOperator(
    task_id='dummy2',
    dag=dag,
    trigger_rule='one_success'
)

dummy1 >> dummy2

如果有一个JoinOperator,它只在一个直接父级成功并且跳过所有其他父级时才触发,而不必使用
trigger\u规则
参数,那就太酷了

或者,解决您面临的问题的方法是触发规则
all(success | skipped)
,您可以将其应用于Dummy3。不幸的是,我认为您还不能创建气流的自定义触发规则

编辑:在这个答案的第一个版本中,我声称触发规则
one_success
all_success
根据DAG中操作员的所有祖先,而不仅仅是直系父母的成功程度触发。这与测试结果不符,事实上,以下实验证明它无效:


将dummy3的触发规则设置为“none\u failed”在任何情况下都会以预期状态结束


编辑:在询问和回答此问题时,
'none\u failed'
触发规则似乎还不存在:它是在2018年11月添加的


请参见

非常感谢将DAG的第二部分放入子DAG的建议。我可能会考虑使用它,尽管我使用的实际工作流中的大多数操作符都是低级的,所以在SDAG中的降级可能不是最好的结构。而且,您确定触发规则的定义是否正确?在文档中,它说:触发器规则的默认值是all_success,可以定义为“当所有直接上游任务都成功时触发此任务”。此外,我完全同意应该有更多的触发规则、JoinOperator或一种方法来定义如果任务失败或上一个任务被跳过,您希望整个工作流失败。@ChristopherBeck您是对的,在他们所说的“直接上游”文档中,事实上,我做了一个实验来证明我的观点是无效的:我将相应地编辑我的答案。谢谢这是一个伟大的新增加气流,将使分支更清洁。