气流-如何设置for循环迭代之间的任务依赖关系?

时间:2018-08-20 17:26:46

标签: python etl airflow

我正在使用Airflow在for循环中运行一组任务。循环的目的是遍历数据库表名称列表并执行以下操作:

for table_name in list_of_tables:
    if table exists in database (BranchPythonOperator)
        do nothing (DummyOperator)
    else:
        create table (JdbcOperator)
    insert records into table (JdbcOperator, Trigger on One Success)

在Web UI上,它看起来像:

tasks in for loop

当前,Airflow从上到下然后从左到右执行此图像中的任务,例如:tbl_exists_fake_table_one-> tbl_exists_fake_table_two-> tbl_create_fake_table_one,等等。

但是,insert的{​​{1}}语句取决于fake_table_two是否被更新,这是当前Airflow无法捕获的依赖关系。 (从技术上讲,这种依赖关系是按fake_table_one的顺序捕获的,但是我相信在更复杂的情况下,这很容易出错)

我希望运行与list_of_table_names相关的所有任务,然后运行与fake_table_one相关的所有任务。如何在Airflow中完成此操作?

下面的完整代码:

fake_table_two

1 个答案:

答案 0 :(得分:2)

存储对每个循环结束时添加的最后一个任务的引用。 然后,在每个循环的开头,检查ref是否存在。 如果引用存在,则将其设置为上游。

类似这样的东西:

last_task = None

for tbl_name in list_of_table_names:


    # run has_table python function
    exists = BranchPythonOperator(
        task_id='tbl_exists_{}'.format(tbl_name),
        python_callable=has_table,
        depends_on_past=False,
        dag=dag
    )

    if last_task:
        last_task >> exists


    ...


    # Run insert or truncate/replace SQL script
    upsert = JdbcOperator(
        task_id='tbl_upsert_{}'.format(tbl_name),
        jdbc_conn_id='conn_id',
        sql = sql_parse(script_path, 'sql/sql_upsert/{}.sql'.format(tbl_name)),
        trigger_rule=TriggerRule.ONE_SUCCESS,
        dag = dag
    )

    last_task = upsert

    ...