本地创建的SAM Lambda应用如何正确添加Python第三方库?
问题场景
本地设备创建SAM Lambda应用,同时部署本地MongoDB服务,计划实现SAM应用与MongoDB的连接,业务代码如下:
import json import pymongo client = pymongo.MongoClient('mongodb://127.0.0.1:27017/') mydb = client['Employee'] def lambda_handler(event, context): information = mydb.employeeInformation record = { 'FirstName' : 'Rehan', 'LastName' : 'CH', 'Department' : "IT" } information.insert_one(record) print("Record added") return { "statusCode": 200, "body": json.dumps( { "message": "Finally my local lambda worked.", } ), }
执行pip install pymongo安装PyMongo依赖后,本地运行SAM Lambda抛出如下导入错误:
{"errorMessage": "Unable to import module 'app': No module named 'pymongo'", "errorType": "Runtime.ImportModuleError", "requestId": "d9a99323-2331-4228-s5f6-dd2e18d6a85e", "stackTrace": []}
手动将Python依赖包放到项目文件夹后问题依然存在,手动放置依赖时的项目目录结构如下:
已知AWS控制台为Lambda添加依赖的操作方法,但不清楚本地开发环境下,如何为本地创建的SAM应用正确添加、配置Python第三方库。
问题根因
全局执行pip安装的依赖存放在Python系统全局路径下,SAM本地运行Lambda时,无论是直接加载代码目录还是通过Docker容器模拟运行环境,都不会读取全局pip安装路径下的包;手动拷贝依赖如果路径不对、或者依赖版本和Lambda运行的Python版本不匹配,也会出现识别失败的问题。
可直接复用的配置方案
方案1:直接将依赖安装到Lambda代码目录(适合单函数、小体量依赖场景)
SAM本地运行时默认会从Lambda处理文件所在目录加载第三方包,操作步骤:
- 进入项目中存放
app.py(Lambda入口文件)的目录 - 执行和SAM配置的Python Runtime版本完全一致的pip命令,将依赖直接安装到当前目录:
pip install pymongo -t .
说明:
-t参数用于指定依赖安装的目标路径,.代表安装到当前目录。安装完成后当前目录会生成pymongo、bson(pymongo自带依赖)相关文件夹,此时执行sam build后再启动本地Lambda即可正常识别依赖。
- 不要混用Python版本:如果SAM配置的Runtime是python3.9,就必须用python3.9对应的pip执行安装,否则会出现包识别失败、C扩展不兼容的问题。
方案2:通过本地Lambda Layer管理依赖(适合多函数共用依赖场景)
如果项目中有多个Lambda函数需要共用pymongo等依赖,可通过本地Layer配置统一管理,避免重复安装:
- 在项目根目录新建层目录结构:
layers/pymongo_layer/python - 进入新建的
python目录,执行依赖安装命令:pip install pymongo -t . - 修改项目根目录下的
template.yaml,配置Layer并关联到对应Lambda函数,示例配置如下:
Resources: # 业务Lambda函数 EmployeeLambda: Type: AWS::Serverless::Function Properties: CodeUri: src/ # 替换为实际的Lambda代码存放目录 Handler: app.lambda_handler Runtime: python3.9 # 替换为实际使用的Python版本 Layers: - !Ref PymongoLayer # 本地pymongo依赖层 PymongoLayer: Type: AWS::Serverless::LayerVersion Properties: LayerName: pymongo-local-layer ContentUri: layers/pymongo_layer/ CompatibleRuntimes: - python3.9 # 和Lambda运行时版本保持一致 RetentionPolicy: Retain
配置完成后执行sam build再启动本地服务,SAM会自动加载Layer中的依赖。
额外避坑:本地MongoDB连接配置修正
当前代码中写的mongodb://127.0.0.1:27017/无法正常连接本地MongoDB:SAM本地Lambda默认运行在独立Docker容器中,容器内的127.0.0.1指向容器自身,不是宿主机的本地服务。
- Mac/Windows环境使用Docker Desktop时,将连接串修改为
mongodb://host.docker.internal:27017/即可访问宿主机部署的MongoDB - Linux环境启动SAM本地服务时添加参数
--add-host host.docker.internal:host-gateway,同样使用上述host.docker.internal的连接串即可正常连接。
内容的提问来源于stack exchange,提问作者M Rehan

