Python 如何将数据从一个运算符传递到另一个运算符

Python 如何将数据从一个运算符传递到另一个运算符,python,airflow,Python,Airflow,我做了一个定制的气流操作符,这个操作符接受一个输入,这个操作符的输出在XCOM上 我想要实现的是使用一些定义的输入调用操作符,将输出解析为可在分支操作符内调用的Python,然后将解析后的输出传递给另一个调用同一操作符树的任务: CustomOperator_Task1 = CustomOperator( data={ 'type': 'custom', 'date': '2017-11-12' }, task_id='CustomOper

我做了一个定制的气流操作符,这个操作符接受一个输入,这个操作符的输出在XCOM上

我想要实现的是使用一些定义的输入调用操作符,将输出解析为可在分支操作符内调用的Python,然后将解析后的输出传递给另一个调用同一操作符树的任务:

CustomOperator_Task1 = CustomOperator(
    data={
        'type': 'custom',
        'date': '2017-11-12'
    },
    task_id='CustomOperator_Task1',
    dag=dag)

data = {}
def checkOutput(**kwargs):
    result = kwargs['ti'].xcom_pull(task_ids='CustomOperator_Task1')

    if result.success = True:
        data = result.data
        return "CustomOperator_Task2"
    return "Failure"

BranchOperator_Task = BranchPythonOperator(
    task_id='BranchOperator_Task ',
    dag=dag,
    python_callable=checkOutput,
    provide_context=True,
    trigger_rule="all_done")

CustomOperator_Task2 = CustomOperator(
    data= data,
    task_id='CustomOperator_Task2',
    dag=dag)

CustomOperator_Task1 >> BranchOperator_Task >> CustomOperator_Task2
在task
CustomOperator\u Task2
中,我想从
branchhoperator\u task
传递解析数据。现在它总是空的
{}


最好的方法是什么?

正如您的评论所示,来自自定义运算符的返回值为None,因此您的xcom_pull应该为空。
请明确使用xcom\u push,因为气流的默认行为可能会随时间而改变。

我现在看到了您的问题。由于气流的工作方式,像您这样设置
数据
变量将不起作用。下一个任务将运行一个完全不同的进程,因此它不会具有
data
设置的上下文

相反,
BranchOperator\u Task
必须将解析后的输出推送到另一个XCom中,以便
CustomOperator\u Task2
可以显式获取它

def checkOutput(**kwargs):
    ti = kwargs['ti']
    result = ti.xcom_pull(task_ids='CustomOperator_Task1')

    if result.success:
        ti.xcom_push(key='data', value=data)
        return "CustomOperator_Task2"
    return "Failure"

BranchOperator_Task = BranchPythonOperator(
    ...)

CustomOperator_Task2 = CustomOperator(
    data_xcom_task_id=BranchOperator_Task.task_id,
    data_xcom_key='data',
    task_id='CustomOperator_Task2',
    dag=dag)
那么你的接线员可能看起来像这样

class CustomOperator(BaseOperator):

    @apply_defaults 
    def __init__(self, data_xcom_task_id, data_xcom_key, *args, **kwargs):
        self.data_xcom_task_id = data_xcom_task_id
        self.data_xcom_key = data_xcom_key
    def execute(self, context):
        data = context['ti'].xcom_pull(task_ids=self.data_xcom_task_id, key=self.data_xcom_key)
        ...

如果只想硬编码参数,则可能不需要这些参数。这取决于您的用例。

您可以将代码片段包含在自定义运算符中吗?
execute()
方法是将输出值返回到push到XCom,还是显式地调用
XCom\u push()
方法?它不显式地执行XCom\u push,但是我相信操作员的返回无论如何都会被推到XCom(通过气流)我可以读取BranchOperator_任务的python_callable。我通过扩展自定义运算符以期望可调用函数检索数据,将函数传递给data参数,然后该函数可以决定返回什么。自定义运算符的返回值不是“无”:-(当我打印“checkOutput”时,它是一个正确显示的对象。我知道将一个函数传递给自定义运算符(更改了自定义运算符)该函数现在决定返回什么,因为现在它正在从xcom读取并返回它。顺便说一句,我认为显式推送到xcom是一个好主意。我为它调整了自定义运算符