气流未从DAG文件以外的文件加载操作员任务

时间:2019-11-05 13:14:36

标签: airflow airflow-operator

通常,我们在定义DAG的同一python文件中定义运算符(请参见this基本示例)。我也是一样。但是我的任务本身就是BIG,使用自定义运算符,因此我想拥有一个多态结构的dag项目,其中所有使用相同运算符的此类任务都位于单独的文件中。为了简单起见,让我举一个非常基本的例子。我有一个操作员x,有几个任务。这是我的项目结构;

main_directory
  ├──tasks
  |  ├──operator_x
  |  |   └──op_x.py
  |  ├──operator_y
  |  :   └──op_y.py
  |   
  └──dag.py 

op_x.py具有以下方法;

def prepare_task():
    from main_directory.dag import dag
    t2 = BashOperator(
        task_id='print_inner_date',
        bash_command='date',
        dag=dag)
    return t2

并且dag.py包含以下代码;

from main_directory.tasks.operator_x import prepare_task

default_args = {
    'retries': 5,
    'retry_delay': dt.timedelta(minutes=5),
    'on_failure_callback': gen_email(EMAIL_DISTRO, retry=False),
    'on_retry_callback': gen_email(EMAIL_DISTRO, retry=True),
    'start_date': dt.datetime(2019, 5, 10)
}
dag = DAG('test_dag', default_args=default_args, schedule_interval=dt.timedelta(days=1))

t1 = BashOperator(
    task_id='print_date',
    bash_command='date',
    dag=dag)

t2 = prepare_task()

现在,当我在气流环境中执行此命令并运行airflow list_dags时,会列出所需的名为test_dag的dag,但是当我执行airflow list_tasks -t test_dag时,我只会得到ID为{{ 1}},而不是ID为print_date的子目录中定义的一个。谁能帮助我了解我在想什么?

1 个答案:

答案 0 :(得分:2)

您的代码将创建循环导入。相反,请尝试以下操作:

op_x.py应该具有:

def prepare_task(dag):
    t2 = BashOperator(
        task_id='print_inner_date',
        bash_command='date',
        dag=dag)
    return t2

dag.py

from main_directory.tasks.operator_x import prepare_task

default_args = {
    'retries': 5,
    'retry_delay': dt.timedelta(minutes=5),
    'on_failure_callback': gen_email(EMAIL_DISTRO, retry=False),
    'on_retry_callback': gen_email(EMAIL_DISTRO, retry=True),
    'start_date': dt.datetime(2019, 5, 10)
}
dag = DAG('test_dag', default_args=default_args, schedule_interval=dt.timedelta(days=1))

t1 = BashOperator(
    task_id='print_date',
    bash_command='date',
    dag=dag)

t2 = prepare_task(dag=dag)

还要确保main_directory中有PYTHONPATH