我有一个简单的气流DAG,可以说2个任务。像这样的东西:
newDirToLoad = Variable.get("path")
filesInDir = next(os.walk(newDirToLoad))[2]
for f in filesInDir:
task1 = BashOperator(
task_id = "load_for_" + str(f),
params = {"fileToProcess" : newDirToLoad + "/" + f}
# ...
)
task1 = BashOperator(
# ...
)
task1 >> task2
此处 path 变量最初设置为某个虚拟目录,以使我的Dag在创建Dag时不会失败。
在某个时候在“ data / to / load /”目录下创建了一个包含文件的新目录之后,我在某个地方编写了一个脚本,该脚本将触发airflow variables -set path data/to/load/$newDir
,然后触发airflow trigger_dag myDag
。这工作得很好,我看到气流GUI中的任务数与$ newDir中存在的文件数相同。但是我认为这是一种调整,允许使用 Variable 功能创建动态任务。有什么好的方法吗?为成功创建Dag,将path变量初始设置为某个虚拟目录是一种不好的做法吗?
答案 0 :(得分:0)
实际上是可能的,而且非常方便。
我建议您看看天文学家团队的这篇博客文章:Dynamically Generating DAGs in Airflow
TL; DR,您可以编写如下内容:
customers = Variable.get("customers_list")
for customer in customers:
dag = DAG(dag_id=f"dag_for_{customer}")
run_first = DummyOperator(
task_id='run_this_first',
dag=dag
)
# for iteration purposes
previous = run_first
for step in Variable.get("customers_steps"):
run_this = DummyOperator(
task_id=f'run_{step}',
dag=dag
)
previous >> run_this
previous = run_this
# From that point, the DAG is complete
# Now, you need to put it in the module globals
globals()[f"dag_for_{customer}"] = dag
之所以可行,是因为Airflow在其扫描的模块中查找DAG对象。在这种情况下,您只需将多个DAG集成到一个模块中,就可以了。
一些优缺点:
优点:
缺点:
享受!