【问题标题】:AWS Lambda - unable to import module 'lambda_function'AWS Lambda - 无法导入模块“lambda_function”
【发布时间】:2018-09-18 23:00:02
【问题描述】:

像我之前的许多其他人一样,我正在尝试运行 AWS Lambda 函数,当我尝试对其进行测试时,我得到了

"errorMessage": "无法导入模块 'lambda_function'"

我的 Handler 设置为 lambda_function.lambda_handler,我确实有一个名为 lambda_function.py 的文件,其中包含一个名为 lambda_handler 的函数。这是一个截图作为证据:

当我在包含的 IDE 中编写内联代码的 sn-ps 时,一切正常,但是当我将完整的程序及其所有依赖项压缩并上传时,出现上述错误。

我正在使用 Numpy 和 Scipy 包,它们非常大。我的压缩目录是 34 MB,我的解压缩目录是 122 MB。我认为这应该没问题,因为压缩目录的限制是 50 MB。它似乎正在上传,因为我看到了消息:

您的 Lambda 函数“one-shot-image-classification”的部署包太大,无法启用内联代码编辑。但是,您现在仍然可以调用您的函数。

我看到一些帖子通过使用 virtualenv 解决了这个问题,但我不熟悉该技术,我不确定如何正确使用它。

我还看到一些帖子说有时依赖项有依赖项,我可能需要包含这些,但我不知道如何找到它。

这是 lambda_function.py 的顶部,应该足以看到我正在使用的库并且我确实有一个 lambda_handler 函数:

import os
import boto3
import numpy as np
from scipy.ndimage import imread
from scipy.spatial.distance import cdist

def lambda_handler(event, context):

    s3 = boto3.resource('s3')

这是我正在上传的目录的解压缩版本的屏幕截图:

如果这可能是一个问题,我还可以发布我的 Lambda 正在使用的策略角色。

非常感谢任何见解!

更新:

这是我尝试过的一种解决方案: 1.git clone https://github.com/Miserlou/lambda-packages 2. 在 Documents 中创建一个名为 new_lambda 的文件夹 3. 将我的 lambda_function.py 和 numpy 文件夹从 lambda-packages 复制到 new_lambda 中,以及我根据文章使用 Docker for AWS 编译的 scipy 库:https://serverlesscode.com/post/scikitlearn-with-amazon-linux-container/ 4. 右键单击​​ new_lambda 文件夹并选择“压缩”来压缩它

我的结果:

无法导入模块“lambda_function”:没有命名模块 'lambda_function'

重申一下,我的文件名为 lambda_function.py 并包含一个名为 lambda_handler 的函数,它接受两个参数(如上所示)。此信息与在 Handler 中看到的相匹配,也可以在上面看到。

我使用的是 Mac 电脑,如果这很重要的话。

更新 2

如果我按照上述步骤,而是通过直接选择要压缩的文件然后右键单击并选择“压缩”来压缩文件,则会收到错误消息

无法导入模块“lambda_function”:无法导入名称“show_config”

此外,预编译的 lambda 包表示它们是为“至少 Python 2.7”编译的,但我的 lambda 运行时是 3.6。这可能是个问题吗?

【问题讨论】:

  • 根据我的经验,这是处理程序函数的命名问题,但您的命名似乎很好。压缩后仔细检查,如果你的处理程序是 foo.bar,那么你的 lambda 函数文件是 foo.py,里面有一个函数 bar()?
  • 正如我的问题所见,我有一个名为 lambda_function.py 的文件,其中有一个名为 lambda_handler 的函数(如上所示)。我将使用我的处理程序设置的屏幕截图更新问题。感谢收看!
  • @SpencerGoff 还会检查 lambda_function.py 是否在部署的 ZIP 的根目录中,而不是在 One-Shot-Learning-Lambda 文件夹中
  • 好主意,我现在正在尝试。我刚刚意识到我一直在误解“root”一词的使用,所以这可能是我的问题。让我们看看。
  • 好的,现在我得到了同样的错误加上“没有名为 numpy 的模块”。可能是因为这也在一次性学习文件夹中。我现在会尝试解决这个问题...

标签: python amazon-web-services aws-lambda


【解决方案1】:

问题是你的本地 numpy 和 pandas 是为本地机器的架构编译的。由于 AWS Lambda 使用自定义 Linux,它们可能不兼容。

所以如果你想使用它们,你有两个选择:

  • 在使用相同 Amazon Linux 的 EC2 实例上编译依赖项 版本为 AWS Lambda 并创建一个部署包。

  • 使用来自here的预编译包之一

附:我在帖子上看过cmets,所以我看到文件和函数的名称是好的,而numpy给你带来了麻烦。

【讨论】:

  • 感谢您的回复,我已通过尝试您的第二个选项更新了问题。如果我不能让它工作,我会尝试你的第一个选项。
  • 我使用了选项 1。它对我有用。谢谢。你拯救了我的一天;-)
【解决方案2】:

解决方案是从 this 源压缩 numpy 和 scipy 预编译包。

【讨论】:

    【解决方案3】:

    我也有类似的问题:

    Unable to import module 'lib/lambda_function': No module named 'lib/lambda_function'
    

    对我和可能对你来说,解决方法是在 lambda_function.py 所在的目录中包含一个空白 __init__.py

    为什么__init__.py 解决了这个问题?

    我了解需要将目录(在我的情况下为 lib,在您的情况下为 .)才能被视为有效的 Python 包。

    这是我基于该假设的参考文档: 5.2.1. Regular packages - Python 3.7.3 documentation

    【讨论】:

    • 嵌套模块名称不应该包含点而不是斜线吗?
    【解决方案4】:

    我在 MacOS 上也遇到过这个问题。我看到你提到你选择文件的方式影响了它是否正常工作。事实证明这是真的!

    在 Mac 上,如果您的 .DS_Store/MacOS 隐藏文件夹潜入该目录,它似乎会破坏 Lambda!

    解决办法是

    rm .DS_Store
    

    在部署 zip 文件夹中。

    【讨论】:

    • 为什么推荐使用-rf
    【解决方案5】:

    我收到了同样的错误,但错误的原因不同。在这里添加一个答案,以防其他疲惫的 * 流浪者发现它有帮助。

    在我的例子中,我试图上传以下目录,其中 package 是一个示例 python 包依赖项,我的函数代码包含在 lambda_function.py 中:

    我正在压缩整个 function 目录,这导致在部署到 lambda 时产生以下文件结构:

    为了正常运行,lambda_function.pypackage 目录都应该在* lambda 目录中。在我的情况下ConfigureAppFlowfunction 目录是导致错误的额外层。

    为了解决这个问题,我没有压缩我的function目录,而是直接压缩里面的两个项目:

    这导致部署到 lambda 时的文件结构如下(忽略 _MACOSX 文件夹):

    总而言之,我敢肯定这个问题有很多不同的原因,但首先要检查的是,您上传到 lambda 的 zip 文件是否正确导致文件结构包含 lambda_function.py 和任何* lambda 目录中的依赖包。

    【讨论】: