Airflow 返回函数中应按顺序运行的任务列表

Airflow 返回函数中应按顺序运行的任务列表,airflow,google-cloud-composer,Airflow,Google Cloud Composer,我想从一个函数返回两个或多个任务,这些任务应该在插入依赖项的位置按顺序运行,请参见下文 t1 = PythonOperator() def generate_tasks(): t2 = PythonOperator() t3 = PythonOperator() return magic(t2, t3) # magic needed here (preferably) t1 >> generate_tasks() # otherwise here # de

我想从一个函数返回两个或多个任务,这些任务应该在插入依赖项的位置按顺序运行,请参见下文

t1 = PythonOperator()

def generate_tasks():
    t2 = PythonOperator()
    t3 = PythonOperator()
    return magic(t2, t3) # magic needed here (preferably)

t1 >> generate_tasks() # otherwise here
# desired result: t1 >> t2 >> t3
这可行吗?据我所知,Airflow 2.0似乎通过一个任务组实现了这一点,但我们正在使用Google的Composer,2.0将暂时无法使用

我发现的最佳解决方法:

t1 = PythonOperator()

def generate_tasks():
    t2 = PythonOperator()
    t3 = PythonOperator()
    return [t2, t3]

tasks = generate_tasks()
t1 >> tasks[0] >> tasks[1]
但是我真的很想把它抽象出来,因为它或多或少地违背了从一个函数返回多个操作符的目的。据最终用户所知,我们希望它是一个单独的单元,即使它可以由2个或更多任务组成

如何在Airflow 2.0中使用任务组:

class Encryptor:
    def encrypt_and_archive(self):
        with TaskGroup("archive_and_encrypt") as section_1:
            encrypt = DummyOperator(task_id="encrypt")
            archive = BashOperator(task_id="archive", bash_command='echo 1')
            encrypt >> archive
        return section_1

with DAG(dag_id="example_return_task_group", start_date=days_ago(2), tags=["example"]) as dag:
    start = DummyOperator(task_id="start")
    encrypt_and_archive = Encryptor().encrypt_and_archive()
    end = DummyOperator(task_id='end')

             # You didn't explain what  
magic(t2, t3)
is. TaskGroup is strictly UI feature it doesn't effect on the DAG logic. According to your description it seems that you are looking for a specific logic (otherwise what is
magic
?).

I believe this is what you are after:

default_args = {
    'owner': 'airflow',
    'start_date': datetime(2021, 1, 24),
}
def generate_tasks():
    operator_list =[]
    for i in range(5): # Replace to generate the logic you wish to dynamically create tasks
        op = DummyOperator(task_id=f"t{str(i)}_task", dag=dag)
        if i>0:
            operator_list[i - 1] >> op
        operator_list.append(op)
    return operator_list

with DAG(
    dag_id='loop',
    default_args=default_args,
    schedule_interval=None,
) as dag:
    start_op = DummyOperator(task_id='start_task')
    end_op = DummyOperator(task_id='end_task')
    tasks = generate_tasks()
    start_op >> tasks[0]
    tasks[-1] >> end_op
类加密机:
def encrypt_和_存档(自):
将任务组(“归档”和“加密”)作为第1节:
加密=DummyOperator(任务\u id=“加密”)
archive=bash操作符(task\u id=“archive”,bash\u命令='echo 1')
加密>>存档
返回段1
使用DAG(DAG_id=“example_return_task_group”,start_date=days_ago(2),tags=[“example”])作为DAG:
start=DummyOperator(任务_id=“start”)
encrypt_and_archive=Encryptor()。encrypt_and_archive()
end=dummy运算符(任务id='end')

#你没有解释什么是
magic(t2,t3)
。 任务组是严格的UI功能,它不会影响DAG逻辑。根据您的描述,您似乎在寻找特定的逻辑(否则什么是
magic
?)

我相信这就是你所追求的:


您可以使用您喜欢的任何运算符替换DummyOperator。

循环执行任务如何?这似乎与我的解决方法实现了相同的效果,因为该函数只返回2个任务。魔法就是这样,一些尚未定义的魔法。我们不能以元组或列表的形式返回它们,因为这样它们就会并行运行,所以我想问一下我是否错过了任何其他选项。我还没有尝试过TaskGroup,但据我所知,我们应该能够使用它对依赖项进行分组:@Frans task group只是UI功能。请添加任务之间所需依赖关系的草图。若并没有所需输出的适当示例,很难理解您的目标。用任务组示例更新了问题。@Frans您的任务组只有2个硬编码运算符。这将创建一个带有一个分支的图,该分支与我显示的分支相同。我假设你有更复杂的逻辑(可能在中间有几个分支),请显示你的实际预期。如果您想在任务组中显示DAG,那么在所有任务组都完全打开时(好像它们甚至不在那里)向我们显示DAG的图像。任务组主要是UI调整。op>>任务组的逻辑只是将op链接到任务组中的所有头。我的回答就像是一头一叶的任务组。@Frans如果你真正想要的是做
开始>>任务[0]
任务[-1]>>结束>/code>,然后以某种方式创建
开始>>X>>结束>
-这在Airflow<2.0中是不可行的,因为你必须升级。正如我所解释的,可以获得功能,但不能使用相同的语法。