如何动态创建具有不同参数的运算符

时间:2018-10-11 09:12:17

标签: airflow

我有以下代码:

def chunck_import(**kwargs):
    ...
    logging.info('Number of pages required is: {0}'.format(num_pages))
    for i in range(1, num_pages + 1):
        ...
        parameter_where = 'where orders_id between {0} and {1}'.format(start,end)
        logging.info(parameter_where)

chunck_import_op = PythonOperator(
    task_id='chunck_import',
    provide_context=True,
    python_callable=chunck_import,
    dag=dag)


start_task_op >> ... >>  chunck_import_op

该运算符创建多个WHERE语句:

INFO - From 7557920 to 7793493
INFO - Number of pages required is: 4
where orders_id between 7607920 and 7657920
where orders_id between 7657921 and 7707920
where orders_id between 7707921 and 7757920
where orders_id between 7757921 and 7793493

现在,我有一个MySqlToGoogleCloudStorageOperator,如下所示:

import_orders_op = MySqlToGoogleCloudStorageOperator(
    task_id='import_orders',
    ...
    sql = 'select * from orders {{ params.where_cluster }}',
    params={'where_cluster': parameter_where},
    dag=dag) 

chunck_import_op知道我需要调用MySqlToGoogleCloudStorageOperator-num_pages的次数,它还会创建我需要作为参数传递的字符串-parameter_where

我的问题是如何根据MySqlToGoogleCloudStorageOperator动态创建num_pages并将parameter_where传递给它。

2 个答案:

答案 0 :(得分:1)

我将继承MySqlToGoogleCloudStorageOperator的子类以自定义查询,并覆盖执行步骤以根据传递给操作员的页面大小参数来生成分页查询。这是一些额外的工作,但建议在此处使用其他选项。

但是,您不能拥有PythonOperator或任何运算符来修改DAG(并使其得到识别和安排)。它所能做的最大事情是:

  1. 在构建where子句之后,使用该子句构造一个MySqlToGoogleCloudStorageOperator并在PythonOperator中对其立即调用execute。这将起作用,并且您将在MySqlToGoogleCloudStorageOperator的日志中看到来自PythonOperator的日志消息。
  2. 使用PythonOperatorTriggerDagRunOperator来触发另一个DAG,仅将MySqlToGoogleCloudStorageOperator传入该子句作为参数,或者首先将其推送到该DAG的XCOM。该其他DAG可能应该将Schedule设置为@None。这将使跟踪日志更加困难,但是可以并行运行DAG。

如果这是我的DAG,我想我的方法(如果不是子类化)将始终在1到X页中处理。让我们建议您的DAG应该处理最多X页的结果,例如X为10。然后从chunck_import_op的父级中定义10个分支。您不需要chunck_import_op或可通话对象。

  • 每个分支都将以ShortCircuitOperator开头,它使用不同的offset参数(0到9)调用相同的可调用对象。此可调用对象将检查offset * page_size是否大于end,如果是,则返回False,并跳过其下游运算符。否则,它将基于偏移量将有效查询推入xcom范围内,并返回True来运行它们。
  • 每个分支都以MySqlToGoogleCloudStorageOperator继续,其查询设置为{{ ti.xcom_pull('<ShortCircuitOperator_N>') }},其中字符串是前一个ShortCircuitOperator的名称。
  • 如果在MySqlToGoogleCloudStorageOperator之后需要其他运算符,请首先添加DummyOperator作为所有这些MySqlToGoogleCloudStorageOperator的子代,然后将trigger_rule {{1} },然后将其他运算符添加为该运算符的子代。

这样,如果需要,您可以运行1到10个分页的查询。它们虽然可以并行运行,但我认为这不是潜在的问题,只需考虑一下即可。

答案 1 :(得分:0)

Airflow为任务(操作员)之间的通信提供了XComs mechanism。在您的具体情况下,chunck_import任务可以先预先计算所有where子句,然后将它们推入XCom中。那么import_orders任务就可以提取XCom,读取所有where子句,并根据需要使用它们。

如果该机制不适用于您的应用程序逻辑,请修改您的问题并解释原因。