【问题标题】:ImportError: no module named [directory] Google App EngineImportError:没有名为 [目录] Google App Engine 的模块
【发布时间】:2019-05-24 01:00:57
【问题描述】:

我不断收到一条错误消息,提示没有名为 backend 的模块,这是我的 webapp2 应用程序所在的目录。

我的文件夹结构:

/project
 /backend
   /env    #python virtual env libraries
   main.py #my main entry point where webapp2 app instance is
   requirements.txt
 app.yaml

我的 app.yaml:

service: default

handlers:
- url: /dist
  static_dir: dist

- url: /.*
  script: backend.main.app

libraries:
- name: webapp2
  version: latest
- name: jinja2
  version: latest

在我的app.yaml 在后端之前,但我决定移动到root。现在,当我在 root 中运行 dev_appserver.py 时,我不断收到 ImportError: No module named backend

我创建了 virualenv 并在 backend 目录中安装了 requirements.txt 包。

编辑:我不确定这是否会有所不同,但是当app.yaml 位于backend 文件夹中时,我已经部署了我的应用程序。我猜这应该没关系,因为我试图通过在我的项目根目录中移动app.yaml 并运行dev_appserver.py app.yaml 来进行本地测试,但是当我这样做时它似乎不起作用。

【问题讨论】:

    标签: python-2.7 google-app-engine yaml


    【解决方案1】:

    包含 GAE 服务的 app.yaml 文件的目录是该服务的顶级目录。此目录的内容是部署服务时将上传到 GAE 的内容。服务代码或配置中引用的所有路径都与此顶级目录相关。因此,移动app.yaml 文件而不相应地更新相关代码和配置将破坏应用程序的功能。

    您似乎没有很好地理解script: 语句的含义。来自Handlers element

    script: 指令必须是 python 导入路径,例如, package.module.app 指向一个 WSGI 应用程序。最后 使用 Python 模块路径的 script: 指令的组件是 模块中全局变量的名称:该变量必须是 WSGI 应用程序,通常按约定称为app

    注意:就像 Python 的 import 语句一样,每个子目录 是一个包必须包含一个名为__init__.py的文件

    因此,假设您的 app.yaml 文件位于您的 project 目录中,

    script: backend.pythonAttack.app

    意思是:

    • backend 目录中有一个__init__.py 文件,以使backend 成为一个包
    • backend 目录中有一个pythonAttack.py 文件,其中一个app 变量指向您的webapp2 应用程序

    根据您的描述,您不符合上述任何条件。

    我的建议:

    • app.yaml 保留在backend 目录中(不需要是python 包目录)
    • 更新其script 行以匹配您的代码。假设您的 webapp2 应用程序的 app 变量实际上在 main.py 文件中,则该行将是:

        script: main.app
      
    • 通过显式传递 app.yaml 文件作为参数在本地运行应用程序(通常是一个好习惯,也是运行具有多个服务和/或 dispatch.yaml 文件的应用程序的唯一方法):

      dev_appserver.py backend/app.yaml
      
    • 将您的服务 python 依赖项存储在 backend/lib 目录中(以遵循命名约定),与您的 virtualenv 包分开

    • env virtualenv 包目录存储在backend 目录之外,以防止在部署服务时将它们不必要地上传到GAE(以及对应用程序操作的潜在干扰)。 virtualenv 的目标是在本地正确模拟 GAE 沙箱,以便您可以正确运行开发服务器。

    可能对构建多服务应用程序感兴趣:Can a default service/module in a Google App Engine app be a sibling of a non-default one in terms of folder structure?

    【讨论】:

    • 感谢您的意见。我的 app.yaml 示例的 script 属性是类型错误。我将它作为 pythonAttack 使用,但将其更改为 main 用于 SO 帖子。如前所述,当我将 app.yaml 放在 backend 目录中时,一切正常,但我想要在项目根目录之外的原因是我可以将我的 dir 目录(静态资产)移动到项目以及不在backend 目录中。我的 app.yaml 与静态目录 dir 位于同一目录中,但如果将我的 app.yaml 移回 backend 中,我不确定如何将我的 app.yaml static_dir 路径指向一个文件。
    • 我基本上希望 app.yaml 位于根目录中,因为我计划将我的应用程序拆分为后端服务和前端服务。但是,正如建议的那样,在 backend 文件夹中添加 init.py 文件后,我不再收到导入错误,一切似乎都正常。但是,有时我的服务器会挂起并且永远不会加载。我想知道这是否与我的 app.yaml 在项目根目录中有关,我的 libraries 设置/属性不指向我安装 virtualenv 的目录。
    • project 目录中将所有服务组合在一起并非不可能(这就是您将.yaml 文件向上移动一级所做的事情)。但是把它做对要麻烦得多。而且您会不必要地上传每个服务中的所有内容。仍然,可能。但我宁愿使用符号链接在服务之间共享静态资产(或任何其他东西)。更清洁恕我直言。
    • 不确定挂起。决定一种方法,如果您仍然看到问题,请将其作为一个单独的问题提出,并针对该问题更新描述。我个人不使用 virtualenv。
    猜你喜欢
    • 2015-01-25
    • 2017-11-12
    • 1970-01-01
    • 2013-03-06
    • 2014-10-30
    • 1970-01-01
    • 2018-07-19
    • 2015-04-24
    • 2018-08-05
    相关资源
    最近更新 更多