Airflow 使用XCOM值在气流中创建动态工作流
现在,我使用这样一个变量创建了多个任务,效果很好Airflow 使用XCOM值在气流中创建动态工作流,airflow,airflow-2.x,Airflow,Airflow 2.x,现在,我使用这样一个变量创建了多个任务,效果很好 with DAG(....) as dag: body = Variable.get("config_table", deserialize_json=True) for i in range(len(body.keys())): simple_task = Operator( task_id = 'task_' + str(i), .....
with DAG(....) as dag:
body = Variable.get("config_table", deserialize_json=True)
for i in range(len(body.keys())):
simple_task = Operator(
task_id = 'task_' + str(i),
.....
但出于某种原因,我需要使用XCOM值,而不是使用变量。
是否可以使用XCOM pull值动态创建任务
我试图像这样设置值,但它不起作用
body=“{{ti.xcom\u pull(key='config\u table',task='get\u config\u table')}”
这是不可能的,通常不建议执行动态任务:
def branch_func(**context)
return f"task_{context['ti'].xcom_pull(key=key)}"
branch = BranchPythonOperator(
task_id="branch",
python_callback=branch_func
)
tasks = [BaseOperator(task_id=f"task_{i}") for i in range(3)]
branch >> tasks
在某些情况下,使用这种方法也不太好(例如,当我有100个可能的任务时),在这种情况下,我建议编写自己的操作符或使用一个PythonOperator。可以从以前任务生成的
xcom
动态创建任务,关于这个主题有更广泛的讨论,例如在这方面。建议的方法之一遵循此结构,下面是我制作的一个工作示例:
示例_file.json:
{
“城市”:[“伦敦”、“巴黎”、“英国”、“纽约”]
}
- 从API、文件或任何来源获取数据。按
的方式推送XCom
def_过程_获得的_数据(ti):
城市列表=ti.xcom\u pull(任务id='get_data')
Variable.set(key='list'u of_cities',
value=list_of_cities['cities'],serialize_json=True)
def_read_file():
将open('dags/sample_file.json')作为f:
data=json.load(f)
#使用return推送到XCom
返回数据
使用DAG('dynamic_tasks_example',schedule_interval='@once',
开始日期=日前(2),
catchup=False)作为dag:
get_data=PythonOperator(
task_id='get_data',
python\u callable=\u read\u文件)
- 添加第二个任务,该任务将从pull from
中提取,并使用稍后用于迭代的数据设置一个XCom
变量
preparation\u task=PythonOperator(
任务\u id='准备任务',
python\u callable=\u进程\u获取的\u数据)
*当然,如果您愿意,可以将两个任务合并为一个任务。我不喜欢这样做,因为通常,我会获取获取数据的一个子集来创建变量
- 读取该
,然后对其进行迭代。定义变量
非常关键default\u var
end=dummy运算符(
任务_id='end',
触发器(规则=“无”\u失败”)
#DAG块内的顶级代码
iterable\u list=变量.get('list\u of\u cities',
default_var=['default_city'],
反序列化(json=True)
- 在循环中声明动态任务及其依赖项。使
唯一<代码>任务组是可选的,可帮助您对UI进行排序任务id
使用任务组(“动态任务组”,
前缀组id=False,
)作为动态任务组:
对于索引,枚举中的城市(iterable_列表):
说你好=蟒蛇操作员(
task_id=f'say_hello_from_{city}',
python\u callable=\u print\u问候语,
op_kwargs={'city_name':city'greeting':'Hello'}
)
说再见(
task_id=f'say_debye_from_{city}',
python\u callable=\u print\u问候语,
op_kwargs={'city_name':city,'greeting':'bye'}
)
#任务组级依赖项
说你好>>说再见
#DAG级依赖关系
获取数据>>准备任务>>动态任务组>>结束
DAG图形视图:
进口:
导入json
从气流导入DAG
从airflow.utils.dates导入天\u
从airflow.models导入变量
从afflow.operators.python_operator导入PythonOperator
从airflow.operators.dummy导入DummyOperator
从afflow.utils.task_组导入任务组
要记住的事情:
- 如果您同时运行相同的
,则所有dag\u都将使用相同的变量,因此您可能需要通过区分它们的名称使其“唯一”dag
- 读取
变量时必须设置默认值,否则,第一次执行可能无法由
计划程序处理
- 气流图视图UI可能不会立即刷新更改。尤其是在从创建动态任务生成的iterable中添加或删除项后的第一次运行中发生
- 如果需要读取多个变量,请务必记住,建议将它们存储在一个JSON值中,以避免不断创建到元数据数据库的连接(本例中的示例)
祝你好运 很好,应该注意TaskGroup是2.0+功能,仅供参考。这很有帮助!!