将一个字符串列表作为依赖任务的参数传递给Airflow

时间:2017-11-01 10:18:44

标签: python airflow

我试图通过XCom将一个字符串列表从一个任务传递到另一个任务,但我似乎无法将推送列表解释为列表。

例如,当我在blah中运行的某个函数ShortCircuitOperator中执行此操作时:

paths = ['gs://{}/{}'.format(bucket, obj) for obj in my_list]
kwargs['ti'].xcom_push(key='return_value', value=full_paths)

然后我想使用这样的列表作为运算符的参数。例如,

run_task_after_blah = AfterBlahOperator(
    task_id='run-task-after-blah',
    ...,
    input_paths="{{ ti.xcom_pull(task_ids='find-paths') }}",
    ...,
)

我希望input_paths等于paths,但它不会,因为渲染发生在第一次然后分配,有些模板渲染将xcom_pull返回转换为 stringified 列表(之后我的AfterBlahOperator插入将其指定为JSON中元素的值。

我尝试将paths连接到由一些分隔符分隔的一个字符串中并将其推送到XCom然后在从XCom拉出时将其拆分但是当XCom首先被渲染时,我得到了split函数时的> stringified 列表,如果paths函数应用于参数,则split的原始连接字符串(如{{1 }}

当可以进一步处理提取的值时,XCom似乎非常适合将单个值用作任务参数或多个值,但不能将多个值转换为一个'作为任务的参数。

有没有办法做到这一点,而无需编写一个精确返回这样的字符串列表的额外函数? 或者我可能过多地滥用XCom,但Airflow中有许多运算符将元素列表作为参数(例如,通常是多个文件的完整路径,这是前一个任务的结果,因此事先不知道)。 / p>

2 个答案:

答案 0 :(得分:3)

Jinja呈现字符串,因此如果您通过模板获取XCom,它将始终是一个字符串。相反,您需要获取可以访问TaskInstance对象的XCom。像这样:

class AfterBlahOperator(BaseOperator):

    def __init__(self, ..., input_task_id, *args, **kwargs):
        ...
        self.input_task_id = input_task_id
        super(AfterBlahOperator, self).__init__(*args, **kwargs)

    def execute(self, context):
        input_paths = context['ti'].xcom_pull(task_ids=self.input_task_id)
        for path in input_paths:
            ...

这类似于您在PythonOperator中提取的方式,XCom docs提供了一个示例。

请注意,您仍然可以支持单独的input_paths参数,以便在DAG中对其进行硬编码时,您只需要额外检查以查看从哪个参数中读取值。

答案 1 :(得分:0)

eval(input_paths)的{​​{1}}方法中调用AfterBlahOperator。这样,可以将字符串化列表转换回列表

execute