通常,我们在定义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
的子目录中定义的一个。谁能帮助我了解我在想什么?
答案 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
。