AWS Lambda - 无法导入模块'lambda_function'

17

和许多人一样,我正在尝试运行一个AWS Lambda函数,但在测试时出现了以下错误:

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

我的Handler设置为lambda_function.lambda_handler,并且我确实有一个名为lambda_function.py的文件,其中包含一个名为lambda_handler的函数。这里是一个截图作为证明: enter image description here

当我在包含的IDE中内联编写代码片段时,一切正常,但当我将带有所有依赖项的完整程序压缩并上传时,就会出现上述错误。

我正在使用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')

这里是我正在上传的目录的未压缩版本的截图: enter image description here

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

非常感谢任何见解!

更新:

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

我的结果:

无法导入模块'lambda_function':没有名为'lambda_function'的模块

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

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

更新2

如果我按照上述步骤,但改为通过直接选择要压缩的文件,然后右键单击并选择“压缩”来压缩文件,则会出现错误

无法导入模块'lambda_function':无法导入名称'show_config'

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


1
正如我在问题中所提到的,我有一个名为lambda_function.py的文件,其中包含一个名为lambda_handler的函数(如上所示)。我将在问题中附上我的处理程序设置的截图。谢谢您的关注! - Spencer Goff
1
@SpencerGoff 还要检查 lambda_function.py 是否在部署的 ZIP 根目录中,而不是在 One-Shot-Learning-Lambda 文件夹内。 - laika
好主意,我现在正在尝试。我刚刚意识到我一直误解了“根”的用法,所以这可能是我的问题。让我们看看。 - Spencer Goff
我已经压缩了目录结构(请参见更新的问题),但仍然出现“无法导入模块'lambda_function'”的错误。我上传的文件名为Archive.zip,这是否有影响? - Spencer Goff
我刚刚重新压缩了所有文件并上传,现在出现以下错误:无法导入模块“lambda_function”: 导入多维数组numpy扩展模块失败。很可能您正在尝试导入一个已损坏的numpy版本。 如果您正在使用numpy git存储库,请尝试git clean -xdf(删除所有未受版本控制的文件)。否则请重新安装numpy。原始错误是:无法导入名称“multiarray”。 - Spencer Goff
显示剩余2条评论
6个回答

11
问题在于您本地的numpy和pandas是为本地机器架构编译的。由于AWS Lambda使用自定义Linux,它们可能不兼容。
因此,如果您想使用它们,您有两个选择:
1. 在使用与AWS Lambda相同的Amazon Linux版本的EC2实例上编译依赖项,并创建部署包。
2. 从这里使用一个预编译的软件包:here 附言:我看了一篇文章的评论,所以我知道文件名和函数名是正确的,而numpy正给您带来麻烦。

感谢您的回复,我已经尝试了您的第二个选项并更新了问题。如果这个方法不起作用,我会尝试您的第一个选项。 - Spencer Goff
我使用了选项1。它对我有用。谢谢。你救了我的一天;-) - Strabek

3
该解决方案是压缩预编译的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 常规包 - Python 3.7.3 文档

嵌套模块名不应该包含斜杠而是应该包含点吗? - NikoNyrh

2

我曾经遇到过同样的错误,但是错误的原因不同。在这里添加一个答案,以防其他疲惫的StackOverflow漫游者发现它有用。

在我的情况下,我试图上传以下目录,其中包是一个示例Python包依赖项,而我的函数代码被封装在lambda_function.py中: enter image description here

我正在压缩整个function目录,这将导致在部署到lambda时出现以下文件结构: enter image description here

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

为了解决这个问题,我没有压缩我的function目录,而是直接压缩了里面的两个项目:enter image description here。当部署到Lambda时,这导致了以下文件结构(忽略_MACOSX文件夹):enter image description here。总之,我确定有很多不同的原因会导致这个问题,但首先要检查的是上传到Lambda的zip文件是否正确地将lambda_function.py和任何依赖包放在您的顶级Lambda目录中。

1
我在MacOS上也遇到了这个问题。我看到你提到了选择文件的方式会影响它是否正常工作。事实证明这是正确的!
在Mac上,如果你的.DS_Store/MacOS隐藏文件夹潜入目录中,似乎会破坏Lambda!
解决方案是:
rm .DS_Store

在部署的zip文件夹中。

1
为什么您建议使用-rf - Alexey Vazhnov

0
压缩文件的方式似乎是问题所在,我刚刚用我的代码文件解决了同样的问题。只需选择要压缩的文件/文件夹,右键单击并进行压缩即可。
由于某种原因,我一直在我的初始项目文件夹中得到一个额外的文件夹,这使得 AWS 无法正确访问我们的文件,因为它只查看根目录而不会深入到第二个目录。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接