无法导入Airflow插件

时间:2017-05-11 06:13:27

标签: airflow

关注Airflow教程here

问题:网络服务器返回以下错误

Broken DAG: [/usr/local/airflow/dags/test_operator.py] cannot import name 
MyFirstOperator

备注: 目录结构如下所示:

airflow_home
├── airflow.cfg
├── airflow.db
├── dags
│   └── test_operators.py  
├── plugins
│   └── my_operators.py   
└── unittests.cfg

我正在尝试在' test_operators.py'中导入插件。像这样:

from airflow.operators import MyFirstOperator

代码与教程中的代码完全相同。

12 个答案:

答案 0 :(得分:4)

Airflow 版本 2 引入了一种新的插件管理机制,如their official documentation 中所述:

<块引用>

在 2.0 版中更改:通过 airflow.{operators,sensor, hooks}. 导入插件中添加的操作符、传感器、钩子,并且这些扩展应该只作为常规 python 模块导入。有关更多信息,请参阅:模块管理和创建自定义 Operator

管理您的python代码所需的一切就是将您的代码放在test.py文件夹中,然后从这里开始寻址文件。假设您已经在位于路径 $AIRFLOW_HOME/plugins/t_plugin/operators/test.pyfrom t_plugin.operators.test import TestClass 文件中编写了 TestClass,在 dag 文件中,您可以这样导入:

{{1}}

答案 1 :(得分:3)

在文章中它确实如此:

class MyFirstPlugin(AirflowPlugin):
    name = "my_first_plugin"
    operators = [MyFirstOperator]

改为使用:

class MyFirstPlugin(AirflowPlugin):
    name = "my_first_plugin"
    operators = [MyFirstOperator]
    # A list of class(es) derived from BaseHook
    hooks = []
    # A list of class(es) derived from BaseExecutor
    executors = []
    # A list of references to inject into the macros namespace
    macros = []
    # A list of objects created from a class derived
    # from flask_admin.BaseView
    admin_views = []
    # A list of Blueprint object created from flask.Blueprint
    flask_blueprints = []
    # A list of menu links (flask_admin.base.MenuLink)
    menu_links = []

也不要使用:

from airflow.operators import MyFirstOperator

According to the airflow article on plugins, it should be:

from airflow.operators.my_first_plugin import MyFirstOperator

如果这不起作用,请尝试:

from airflow.operators.my_operators import MyFirstOperator

如果这不起作用,请检查启动时的Web服务器日志以获取更多信息。

答案 2 :(得分:3)

我重新启动了网络服务器,现在一切正常。

以下是我认为可能发生的事情:

  1. 在开始使用教程示例之前,我尝试运行自己的插件和dag。在我修复的第一次运行时出现了一个小的语法错误,但是在修复之后我开始得到&#39;无法导入名称&#39;错误。
  2. 我删除了插件和dag,并尝试使用教程中的那个来查看发生了什么。
  3. 我的猜测是步骤1中的错误以某种方式影响了第2步。

答案 3 :(得分:2)

我使用气流 1.10 。 如果您要导入的是自定义运算符,则可以将其上传到airflow plugins文件夹,然后在DAG中将导入指定为:

来自 [文件名] 导入 [类名]

其中: filename是您的插件文件的名称 classname是您的班级名称。

例如: 如果文件名是 my_first_plugin ,并且类的名称是 MyFirstOperator 那么导入将是:

my_first_plugin 导入 MyFirstOperator

在使用 airflow 1.10

时为我工作

谢谢!希望这对您有帮助!

答案 4 :(得分:1)

我在跟随these tutorials时遇到了相同的错误。

但是,我的错是我在' ' 中使用了空格字符task_idAirflow不支持。

很明显,该错误并未指向实际问题。重新启动气流schedulerwebserver,然后在 WebUI 上显示正确的错误消息。

答案 5 :(得分:1)

为了解决该问题,我必须更新文件airflow.cfg中的插件路径。

您的Airflow插件的存储位置:

plugins_folder = /airflow/plugins

答案 6 :(得分:1)

根据文档-

  

plugins文件夹中的python模块被导入,并且钩子,运算符,传感器,宏,执行程序和Web视图被集成到Airflow的主要集合中并可供使用。

,并且在1.10.1版中正常运行

答案 7 :(得分:0)

就我而言,我设法通过以下步骤创建了自定义运算符:

  1. 气流10.3
  2. 在DAG文件from airflow.operators import MacrosPostgresOperator
  3. 在〜/ airflow / plugins文件夹中,我有一个python文件custom_operator.py,代码很简单
from airflow.plugins_manager import AirflowPlugin
from airflow.operators.postgres_operator import PostgresOperator

 class MacrosPostgresOperator(PostgresOperator):
    template_fields = ('sql', 'parameters')

class MacrosFirstPlugin(AirflowPlugin):
    name = "macros_first_plugin"
    operators = [MacrosPostgresOperator]

答案 8 :(得分:0)

您必须停止(CTRL-C)并重新启动Airflow Web服务器和调度程序。

答案 9 :(得分:0)

在为Airflow文档苦苦挣扎并在这里尝试了一些答案而没有成功之后,我发现了this approach from astronomer.io

正如他们所指出的那样,构建气流插件可能会令人困惑,也许不是添加钩子和操作员的最佳方法。

  

自定义挂钩和操作员是扩展气流以满足您需求的强大方法。但是,对于   实施它们。根据Airflow文档,它们可以是   使用Airflow的插件机制添加的。但是,这过于复杂   这个问题并导致许多人感到困惑。气流均匀   考虑弃用对钩子和钩子使用插件机制   运营商向前迈进。

因此,我没有摆弄插件API,而是遵循了天文学家的方法,如下所示设置了Airflow。

dags
└── my_dag.py               (contains dag and tasks)
plugins
├── __init__.py
├── hooks
│   ├── __init__.py
│   └── mytest_hook.py      (contains class MyTestHook)
└── operators
    ├── __init__.py
    └── mytest_operator.py  (contains class MyTestOperator)

使用这种方法,我的操作员和hook的所有代码都完全存在于各自的文件中-并且没有令人困惑的插件文件。所有__init__.py文件都是空的(不同于将插件代码放入其中的一些同样令人困惑的方法)。

对于所需的import,请考虑Airflow实际如何使用plugins目录:

  

Airflow运行时,会将dags /,plugins /和config /添加到PATH

这意味着执行from airflow.operators.mytest_operator import MyTestOperator可能行不通。 取而代之的是from operators.mytest_operator import MyTestOperator(注意,在上面的设置中与from directory/file.py import Class对齐)。

我文件中的工作片段如下所示。

my_dag.py:

from airflow import DAG
from operators.mytest_operator import MyTestOperator
default_args = {....}
dag = DAG(....)
....
mytask = MyTestOperator(task_id='MyTest Task', dag=dag)
....

my_operator.py:

from airflow.models import BaseOperator
from hooks.mytest_hook import MyTestHook

class MyTestOperator(BaseOperator):
    ....
    hook = MyTestHook(....)
    ....

my_hook.py:

class MyTestHook():
    ....

这对我有用,比尝试将AirflowPlugin子类化要简单得多。但是,如果要更改Web服务器用户界面,它可能对您不起作用:

  

注意:对于使用以下功能的插件,仍必须使用Plugins机制   更改为Web服务器用户界面。

顺便说一句,在此之前我遇到的错误(现已解决):

ModuleNotFoundError: No module named 'mytest_plugin.hooks.mytest_hook'
ModuleNotFoundError: No module named 'operators.mytest_plugin'

答案 10 :(得分:0)

在同一教程中,我遇到了同样的问题。对我有用的是将MyFirstOperator的导入替换为:

from airflow_home.plugins.my_operators import MyFirstOperator

答案 11 :(得分:0)

比方说,以下是您在my_operators.py中实现的自定义插件,

class MyFirstPlugin(AirflowPlugin):
    name = "my_first_plugin"
    operators = [MyFirstOperator]

然后根据Airflow documentation,您必须导入以下结构,

from airflow.{type, like "operators", "sensors"}.{name specified inside the plugin class} import *

因此,在这种情况下,您应按以下方式导入

from airflow.operators.my_first_plugin import MyFirstOperator