Python 气流中的动态任务定义
我目前正在尝试使用Airflow来编排一个流程,其中一些操作符是动态定义的,并且依赖于另一个(早期)操作符的输出 在下面的代码中,t1使用新记录更新文本文件(这些记录实际上是从外部队列读取的,但为了简单起见,我在这里将它们硬编码为a、B和C)。然后,我想为从该文本文件读取的每条记录创建单独的运算符。这些操作符将分别创建目录A、B和C,在Airflow UI中,它们将被视为单独的bash进程create_directory_A、create_directory_B和create_directory_CPython 气流中的动态任务定义,python,bash,airflow,orchestration,Python,Bash,Airflow,Orchestration,我目前正在尝试使用Airflow来编排一个流程,其中一些操作符是动态定义的,并且依赖于另一个(早期)操作符的输出 在下面的代码中,t1使用新记录更新文本文件(这些记录实际上是从外部队列读取的,但为了简单起见,我在这里将它们硬编码为a、B和C)。然后,我想为从该文本文件读取的每条记录创建单独的运算符。这些操作符将分别创建目录A、B和C,在Airflow UI中,它们将被视为单独的bash进程create_directory_A、create_directory_B和create_directory
dag = DAG('Test_DAG',
description="Lorem ipsum.",
start_date=datetime(2017, 3, 20),
schedule_interval=None,
catchup=False)
def create_text_file(list_of_rows):
text_file = open('text_file.txt', "w")
for row in list_of_rows:
text_file.write(row + '\n')
text_file.close()
def read_text():
txt_file = open('text_file.txt', 'r')
return [element for element in txt_file.readlines()]
t1 = PythonOperator(
task_id='Create_text_file',
python_callable=create_text_file,
op_args=[['A', 'B', 'C']],
dag=dag
)
for row in read_text():
t2 = BashOperator(
task_id='Create_directory_{}'.format(row),
bash_command="mkdir {{params.dir_name}}",
params={'dir_name': row},
dag=dag
)
t1 >> t2
在中,我可以看到调度程序将定期执行它[DAG],以反映任何更改。这是否意味着存在这样一种风险:即使我的t1操作符在t2之前执行,在更新之前也会为记录列表创建bash操作符(就像在评估DAG时那样)?此代码实际上将创建
t2
的一个实例,该实例将由bash操作符使用从read\u text()获取的最后一行构建。我肯定这不是你想要的
更好的方法是为t2
操作符创建一个单独的DAG,该DAG在t1
写入文件时触发。关于这一点,有一个问题可能会有所帮助:您不能根据上游任务的输出动态创建任务。你把时间表和执行时间搞混了。DAG定义和任务在计划时间创建。DAG运行和任务实例在执行时创建。只有任务实例才能生成输出
气流调度器将在计划时间使用text_file.txt
包含的任何内容构建动态图形。然后将这些任务发送给工人
工作者最终将执行t1
任务实例并创建一个新的text_file.txt
,但此时,调度程序已经计算出t2
任务列表,并将其发送给工作者
因此,无论最新的t1
任务实例转储到text\u file.txt
中,都将在计划程序下次决定运行DAG时使用
如果您的任务很快,并且您的工作人员没有积压,则这将是上一次DAG运行的内容。如果它们是积压的,text\u file.txt
内容可能会过时,如果您真的运气不好,调度程序会在任务实例写入文件时读取该文件,您将从read\u text()
中获得不完整的数据,谢谢Steve。我意识到我在t1
中遗漏了额外的方括号。目前,代码确实为从read\u text()
读取的所有行生成t2
。它得到的行列表是否有过时的风险?啊,好的。我仍然认为一个单独的DAG会更干净,更容易维护,我不会依赖它的工作,因为它是。多个DAG在Airflow上非常常见/什么可能是一种好的方法:查询时间表上的表,如果找到,则为每一行运行任务?感谢您的解释!我们如何确保t1在t2之前运行?这与子DAG有关吗?这就是t1>>t2
所做的-它建立了一个任务的有向无环图(DAG),描述了任务应该按什么顺序运行。