我已经看到了在DAG脚本本身中创建的动态DAG的多个示例。
如果获取所需元数据的过程很耗时/也需要挂钩/运算符怎么办?操作员可以创建新的DAG(或正在执行的DAG中的SubDAG)吗?
例如连接到一个/多个数据库,提取各种元数据并生成每个表的ETL过程(简单情况-使用JDBC将带有标头的假脱机数据缓冲到本地文件,并将其复制到S3)?
最简单的解决方案-两个DAGS,一个获取所有必需的元数据并存储在一个文件中,另一个DAG检查该文件(每个调度程序检测信号)并动态计划作业(如果存在)。但是随后,需要在DAG定义文件中复制某些Hooks / Operators逻辑(计划阶段和执行阶段的混合)。
编辑8/17 :甚至具有两个独立DAG的解决方案也无法按预期工作。当远程工作者获取要处理的动态任务时,它将加载DAG文件和NEEDS以再次执行整个计划部分。简单的例子:
spooler.py
from airflow import DAG
from airflow.operators.subdag_operator import SubDagOperator
from subdags.spooler_subdag import spooler_subdag
import os
from datetime import datetime
lines = []
local_filename = '/location/to/file/with/tables/to/be/loaded'
if os.path.isfile(local_filename):
with open(local_filename) as f:
lines = f.read().splitlines()
default_args = {
'owner': 'airflow',
'depends_on_past': False,
(...)
}
dag = DAG('spooler', default_args=default_args, schedule_interval="@daily")
for line in lines:
table, method = line.split(' ')
subdag = SubDagOperator(
task_id=table,
subdag=spooler_subdag('spooler', table, table, method, default_args),
default_args=default_args,
dag=dag
)
subdags / spooler_subdag.py
from airflow.models import DAG
from airflow.operators import JavaOperator
def spooler_subdag(parent_dag_name, child_dag_name, table, method, args):
dag_subdag = DAG(
dag_id='%s.%s' % (parent_dag_name, child_dag_name),
default_args=args,
schedule_interval="@daily"
)
extract = JavaOperator(
task_id='extract_task',
xcom_push=True,
script='spooler',
script_params=[table, method],
dag=dag_subdag)
return dag_subdag
当远程工作程序上不存在“ / location / to / file / with / tables / to / be / loaded”文件时,执行失败。我想念什么吗?