关于芹菜:气流-python文件不在同一个dag文件夹中

Airflow - Python file NOT in the same DAG folder

我尝试使用气流来执行一个简单的任务python。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from __future__ import print_function
from airflow.operators.python_operator import PythonOperator
from airflow.models import DAG
from datetime import datetime, timedelta


from pprint import pprint

seven_days_ago = datetime.combine(datetime.today() - timedelta(7),
                                  datetime.min.time())

args = {
    'owner': 'airflow',
    'start_date': seven_days_ago,
}

dag = DAG(dag_id='python_test', default_args=args)


def print_context(ds, **kwargs):
    pprint(kwargs)
    print(ds)
    return 'Whatever you return gets printed in the logs'

run_this = PythonOperator(
    task_id='print',
    provide_context=True,
    python_callable=print_context,
    dag=dag)

如果我尝试,例如:

airflow test python_test print 2015-01-01

它起作用了!

现在我想把我的def print_context(ds, **kwargs)函数放到其他python文件中。所以我创建了一个名为:simple_test.py and change:

1
2
3
4
5
run_this = PythonOperator(
    task_id='print',
    provide_context=True,
    python_callable=simple_test.print_context,
    dag=dag)

现在我再次尝试跑步:

airflow test python_test print 2015-01-01

好吧!它仍然有效!

但是,如果我创建了一个模块,例如,带有文件SimplePython.py的worker模块,请导入(from worker import SimplePython文件),然后尝试:

airflow test python_test print 2015-01-01

它给出了以下信息:

ImportError: No module named worker

问题:

  • 是否可以导入DAG定义内的模块?
  • airflow+celery将如何在工作节点上分发所有必需的python源文件?

  • 您可以根据以下内容打包DAG的依赖项:

    https://airflow.apache.org/concepts.html_packaged dags

    To allow this you can create a zip file that contains the dag(s) in the root of the zip file and have the extra modules unpacked in directories.
    For instance you can create a zip file that looks like this:

    1
    2
    3
    4
    my_dag1.py
    my_dag2.py
    package1/__init__.py
    package1/functions.py

    Airflow will scan the zip file and try to load my_dag1.py and my_dag2.py. It will not go into subdirectories as these are considered to be potential packages.

    当使用celeryexecutor时,您需要手动同步DAG目录,Airflow不会为您处理这些问题:

    https://airflow.apache.org/configuration.html?Highlight=缩放比例为20%缩小比例为20%芹菜

    The worker needs to have access to its DAGS_FOLDER, and you need to synchronize the filesystems by your own means


    虽然将DAG打包到一个zip中(如docs中所述)是我见过的唯一受支持的解决方案,但是您也可以导入DAGS文件夹中的模块。如果使用其他工具(如puppet&git)自动同步DAGS文件夹,这将非常有用。

    我不清楚您的目录结构,所以这里有一个基于典型的Python项目结构的DAGS文件夹示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    └── airflow/dags  # root airflow dags folder where all dags live
        └── my_dags  # git repo project root
            ├── my_dags  # python src root (usually named same as project)
            │   ├── my_test_globals.py  # file I want to import
            │   ├── dag_in_package.py
            │   └── dags
            │        └── dag_in_subpackage.py
            ├── README.md  # also setup.py, LICENSE, etc here
            └── dag_in_project_root.py

    我遗漏了(必需的)__init__.py文件。注意三个示例DAG的位置。几乎可以肯定的是,所有的匕首都只能在这些地方使用一个。为了举例,我把它们都放在这里,因为进口不重要。从其中任何一个进口my_test_globals

    1
    from my_dags.my_dags import my_test_globals

    我相信这意味着气流将dags文件夹的每个子目录作为python包加载。在我的例子中,它是额外的中间项目根目录,妨碍了典型的包内绝对导入。因此,我们可以这样重组这个气流项目:

    1
    2
    3
    4
    5
    6
    7
    8
    └── airflow/dags  # root airflow dags folder where all dags live
        └── my_dags  # git repo project root & python src root
            ├── my_test_globals.py  # file I want to import
            ├── dag_in_package.py
            ├── dags
            │    └── dag_in_subpackage.py
            ├── README.md  # also setup.py, LICENSE, etc here
            └── dag_in_project_root.py

    使进口产品看起来像我们期望的那样:

    1
    from my_dags import my_test_globals


    对于第二个问题:airflow+celery将如何在工作节点上分发所有必要的python源文件?

    来自文档:工作人员需要访问其dags_文件夹,并且您需要通过自己的方式同步文件系统。一个常见的设置是将您的dags_文件夹存储在Git存储库中,并使用chef、puppet、ansible或任何您用于在环境中配置机器的工具在机器之间进行同步。如果所有的盒子都有一个公共的安装点,那么在那里共享管道文件也可以。

    http://pythonhosted.org/airflow/installation.html?亮点=厨师


    对于你的第一个问题,这是可能的。

    我想你应该在与SimplePython.py相同的目录下创建一个名为__init__.py的空文件(在你的例子中是worker目录)。这样,worker目录将被视为python模块。

    然后在DAG定义中,尝试from worker.SimplePython import print_context

    在您的例子中,我想最好是编写一个气流插件,因为您可能希望升级气流核心项目而不删除您的定制功能。