如何动态迭代上游任务的输出以在气流中创建并行任务?

时间:2017-07-25 21:56:42

标签: python python-3.x airflow apache-airflow

考虑以下DAG示例,其中第一个任务get_id_creds从数据库中提取凭据列表。此操作告诉我数据库中的哪些用户能够运行进一步的数据预处理,并将这些ID写入文件/tmp/ids.txt。然后,我将这些ID扫描到我的DAG中,并使用它们生成可以并行运行的upload_transaction任务列表。

我的问题是:使用气流是否有更正确,更动态的方式来做到这一点?我在这里感觉笨拙和脆弱。如何直接将有效ID列表从一个进程传递到定义后续下游进程?

from datetime import datetime, timedelta
import os
import sys

from airflow.models import DAG
from airflow.operators.python_operator import PythonOperator

import ds_dependencies

SCRIPT_PATH = os.getenv('DASH_PREPROC_PATH')
if SCRIPT_PATH:
    sys.path.insert(0, SCRIPT_PATH)
    import dash_workers
else:
    print('Define DASH_PREPROC_PATH value in environmental variables')
    sys.exit(1)

default_args = {
  'start_date': datetime.now(),
  'schedule_interval': None
}

DAG = DAG(
  dag_id='dash_preproc',
  default_args=default_args
)

get_id_creds = PythonOperator(
    task_id='get_id_creds',
    python_callable=dash_workers.get_id_creds, 
    provide_context=True,
    dag=DAG)

with open('/tmp/ids.txt', 'r') as infile:
    ids = infile.read().splitlines()

for uid in uids:
    upload_transactions = PythonOperator(
        task_id=uid,
        python_callable=dash_workers.upload_transactions,
        op_args=[uid],
        dag=DAG)
    upload_transactions.set_downstream(get_id_creds)

2 个答案:

答案 0 :(得分:5)

Per @Juan Riza的建议我查看了这个链接:Proper way to create dynamic workflows in Airflow。这几乎就是答案,虽然我能够简化解决方案,我认为我会在这里提供我自己的修改版本的实现:

sendmail user@xxxxx.com < mailtest.txt 

from datetime import datetime import os import sys from airflow.models import DAG from airflow.operators.python_operator import PythonOperator import ds_dependencies SCRIPT_PATH = os.getenv('DASH_PREPROC_PATH') if SCRIPT_PATH: sys.path.insert(0, SCRIPT_PATH) import dash_workers else: print('Define DASH_PREPROC_PATH value in environmental variables') sys.exit(1) ENV = os.environ default_args = { # 'start_date': datetime.now(), 'start_date': datetime(2017, 7, 18) } DAG = DAG( dag_id='dash_preproc', default_args=default_args ) clear_tables = PythonOperator( task_id='clear_tables', python_callable=dash_workers.clear_db, dag=DAG) def id_worker(uid): return PythonOperator( task_id=uid, python_callable=dash_workers.main_preprocess, op_args=[uid], dag=DAG) for uid in capone_dash_workers.get_id_creds(): clear_tables >> id_worker(uid) 清除将由于该过程而重建的数据库。 clear_tables是一个根据id_worker返回的ID值数组动态生成新预处理任务的函数。任务ID只是相应的用户ID,尽管它很容易成为索引get_if_creds,如上面提到的示例所示。

注意那个bitshift运算符(i)向后看我,因为<<任务应该首先出现,但它似乎正在起作用这个案例。

答案 1 :(得分:1)

考虑到Apache Airflow是一个工作流管理工具,即。它确定了用户定义的任务与作为数据流管理工具的apache Nifi进行比较(作为示例)之间的依赖关系,即。这里的依赖关系是通过任务传递的数据。

那就是说,我认为你的方法是正确的(我的评论基于发布的代码) Airflow提供了一个名为XCom的概念。它允许任务通过传递一些数据在它们之间“交叉通信”。传递的数据应该有多大?由你来测试!但一般来说它应该不是那么大。我认为它是以键,值对的形式存储在气流元数据库中,即你不能传递文件,但是带有id的列表可以工作。

就像我说过你应该自己测试一下。我很高兴知道你的经历。 Here是一个示例dag,它演示了使用XComhere是必要的文档。干杯!