BranchPythonOperator之后的气流任务未正确失败和成功
在我的DAG中,我有一些任务应该只在周六运行。因此,我使用BranchPythonOperator在星期六的任务和Dummy任务之间进行分支。之后,我加入这两个分支,并希望运行其他任务 工作流如下所示:BranchPythonOperator之后的气流任务未正确失败和成功,python,airflow,Python,Airflow,在我的DAG中,我有一些任务应该只在周六运行。因此,我使用BranchPythonOperator在星期六的任务和Dummy任务之间进行分支。之后,我加入这两个分支,并希望运行其他任务 工作流如下所示: 在这里,我将dummy3的触发规则设置为“一次成功”,一切正常 我遇到的问题是,BranchPythonOperator的上游出现故障: BranchPythonOperator和分支正确地具有状态'upstream\u failed',但是加入分支的任务变为'skipped',因此整个工作
在这里,我将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您是对的,在他们所说的“直接上游”文档中,事实上,我做了一个实验来证明我的观点是无效的:我将相应地编辑我的答案。谢谢这是一个伟大的新增加气流,将使分支更清洁。