Airflow 气流:当短路跳过某些上游时,运行任务
我有一个任务,我将调用具有多个上游连接的Airflow 气流:当短路跳过某些上游时,运行任务,airflow,Airflow,我有一个任务,我将调用具有多个上游连接的final。当ShortCircuitOperator跳过其中一个上游时,此任务也会被跳过。我不想跳过final任务,因为它必须报告DAG成功 为了避免它被跳过,我使用了trigger\u rule='all\u done',但它仍然被跳过 如果我使用BranchPythonOperator而不是ShortCircuitOperatorfinal任务不会被跳过。分支工作流似乎是一个解决方案,尽管不是最优的,但现在final将不考虑上游任务的失败 如何使其仅
final
。当ShortCircuitOperator跳过其中一个上游时,此任务也会被跳过。我不想跳过final
任务,因为它必须报告DAG成功
为了避免它被跳过,我使用了trigger\u rule='all\u done'
,但它仍然被跳过
如果我使用BranchPythonOperator
而不是ShortCircuitOperator
final
任务不会被跳过。分支工作流似乎是一个解决方案,尽管不是最优的,但现在final
将不考虑上游任务的失败
如何使其仅在上游成功或跳过时运行
示例短路DAG:
来自气流导入DAG
从airflow.operators.dummy_operator导入dummy operator
从afflow.operators.python_operator导入ShortCircuitOperator
从日期时间导入日期时间
从随机导入randint
默认参数={
“所有者”:“气流”,
“开始日期”:日期时间(2018年8月1日)
dag=dag(
“短路测试”,
默认参数=默认参数,
计划时间间隔=“****”,
catchup=错误)
def短路\u fn():
返回randint(0,1)=1
task_1=DummyOperator(dag=dag,task_id='task_1')
task_2=DummyOperator(dag=dag,task_id='task_2')
work=dummy运算符(dag=dag,task\u id='work')
short=shortcircuit操作符(dag=dag,task\u id='short\u circuit',python\u callable=shortcircuit\u fn)
final=dummy操作符(dag=dag,task\u id=“final”,trigger\u rule=“all\u done”)
任务1>>简短>>工作>>最终
任务1>>任务2>>最终
样本分支DAG:
来自气流导入DAG
从airflow.operators.dummy_operator导入dummy operator
从afflow.operators.python_operator导入BranchPythonOperator
从日期时间导入日期时间
从随机导入randint
默认参数={
“所有者”:“气流”,
“开始日期”:日期时间(2018年8月1日)
dag=dag(
“分支测试”,
默认参数=默认参数,
计划时间间隔=“****”,
catchup=错误)
#这两个函数仅用于保护任务不被作为分支运算符的直接依赖项跳过
to_do_work=dummy操作员(dag=dag,task\u id='to_do_work')
to_skip_work=dummy运算符(dag=dag,task_id='to_skip_work')
def分支_fn():
如果randint(0,1)=1,则返回到\u do\u work.task\u id,否则返回到\u skip\u work.task\u id
task_1=DummyOperator(dag=dag,task_id='task_1')
task_2=DummyOperator(dag=dag,task_id='task_2')
work=dummy运算符(dag=dag,task\u id='work')
branch=BranchPythonOperator(dag=dag,task\u id='branch',python\u callable=branch\u fn)
final=dummy操作符(dag=dag,task\u id=“final”,trigger\u rule=“all\u done”)
任务1>>分支>>完成工作>>工作>>最终
分支>>跳过工作>>最终
任务1>>任务2>>最终
我通过执行final
任务来检查上游实例的状态,从而使其正常工作。我发现访问它们的状态的唯一方法是查询数据库,这并不漂亮
##有问题代码的附加导入
#从气流导入气流异常
#从airflow.models导入TaskInstance
#从afflow.operators.python_operator导入PythonOperator
#从airflow.settings导入会话
#从airflow.utils.state导入状态
#从airflow.utils.trigger\u规则导入TriggerRule
定义所有上游\u成功\u或跳过(dag、任务、任务\u实例、**上下文):
"""
直接查找上游任务实例,并统计有多少实例未处于首选状态。
如果没有非首选状态的实例,则返回True。
"""
上游任务id=[t.task\u任务中t的id.get\u直接亲属(上游=真)]
会话=会话()
查询=(会话)
.query(TaskInstance)
.过滤器(
TaskInstance.dag_id==dag.dag_id,
TaskInstance.execution\u date.in.([task\u instance.execution\u date]),
TaskInstance.task\u id.in\u(上游任务\u id)
)
)
上游任务实例=query.all()
不满意的_任务_实例=[ti代表上游_任务_实例中的ti,如果ti.state不在[state.SUCCESS,state.SKIPPED]]
打印(不满意的任务实例)
返回len(不满意的任务实例)==0
最终定义fn(**上下文):
"""
如果上游任务实例具有不需要的状态,则失败
"""
如果并非所有上游都成功或跳过(**上下文):
引发AirflowException(“并非所有上游任务都成功。”)
#做事
#将在上游任务实例完成(包括失败)时运行
最终=蟒蛇算子(
dag=dag,
任务\u id=“最终”,
trigger\u rule=TriggerRule.ALL\u完成,
python\u callable=final\u fn,
提供(上下文=真)
我在原来的基础上开发了自定义ShortCircuitOperator:
类ShortCircuitOperator(PythonOperator,SkipMixin):
"""
仅当满足条件时才允许工作流继续。否则
工作流“短路”和仅依赖此操作员的下游任务
被跳过。
ShortCircuit运算符派生自Python运算符。它计算
如果条件为False,则条件和短路工作流。是否
仅依赖此运算符的下游任务将标记为“跳过”状态。
如果条件为真,则下游任务将正常进行。
条件由“python\u callable”的结果决定。
"""
def find_tasks_to_skip(self、task、find_tasks=None):
如果未找到\u任务:
找到的任务=[]
直接亲属=任务。获取直接亲属(上游=False)
对于直系亲属中的t:
如果len(t.上游任务ID)==1:
已找到\u任务。追加(t)
self.find_tasks_to_skip(t,find_tasks)
返回找到的任务
def执行(自身、上下文):
条件=超级(ShortCircuitOperator,self)。执行(上下文)
def fn_short_circuit(**context):
if <<<some condition>>>:
raise AirflowSkipException("Skip this task and individual downstream tasks while respecting trigger rules.")
check_date = PythonOperator(
task_id="check_if_min_date",
python_callable=_check_date,
provide_context=True,
dag=dag,
)
task1 = DummyOperator(task_id="task1", dag=dag)
task2 = DummyOperator(task_id="task2", dag=dag)
work = DummyOperator(dag=dag, task_id='work')
short = ShortCircuitOperator(dag=dag, task_id='short_circuit', python_callable=fn_short_circuit
final_task = DummyOperator(task_id="final_task",
trigger_rule='none_failed',
dag=dag)
task_1 >> short >> work >> final_task
task_1 >> task_2 >> final_task