我正在尝试使用 APi Gateway 构建一个 AWS Lambda 函数,该函数使用 pyodbc python 包。我已经按照文档中提到的步骤进行操作。我不断收到以下错误无法导入模块"app":libodbc.so.2:无法打开共享对象文件:当我测试运行 Lambda 函数时没有这样的文件或目录。
任何帮助表示赞赏。当我使用 Chalice 部署我的包时,我遇到了同样的错误。看来可能是我需要安装 unixodbc-dev。知道如何通过 AWS Lambda 做到这一点吗?
只需从这里解压缩此文件 - github - lambda_packages/pyodbc。这其中包含 .so 文件。
现在将您的 python 代码和 .so 文件打包在一起,并上传到 AWS lambda。供参考的文件夹结构应如下所示。
lambda_function.py
libodbc.so.2
pyodbc.so
<name_this_zip>.zip
No subfolders exist
编辑:创建了一个 lambda 层并将其保存以供重复使用。在这里得到它 - https://github.com/kuharan/Lambda-Layers
pyodbc 使用一些原生库。因此,您不能只将site-packages
的内容复制到 Lambda,因为您的操作系统可能不是 Amazon Linux。
因此,您需要在 Amazon Linux 实例上安装 pyodbc 并使用生成的库:
https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html
或者你可以从这里获取,如果那里有的话:
https://github.com/Miserlou/lambda-packages
首先,使用 yum install unixODBC unixODBC-devel
安装 unixODBC
和unixODBC-devel
软件包。此步骤将安装 pyodbc 模块所需的所有内容。
您缺少的库位于您的 Amazon Linux 实例/usr/lib64
文件夹中。将库复制到 python 项目的根文件夹(libodbc.so.2 只是一个符号链接,请确保复制符号链接和库本身,如所列所示(: libodbc.so
、libodbc.so.2
和 libodbc.so.2.0.0
尝试运行此脚本以将依赖项收集到 S3 存储桶中,然后将其添加到您的 lambda 部署程序包中。
"""
This lambda function collects python pip dependencies, and uploads them to S3 bucket
as a single tar.gz file. Example input for Lambda event:
event = {
"prefix" : "myPackage",
"saveToS3Bucket" : "my-s3-bucket",
"saveToS3Key" : "package-jwt.tar.gz",
"requirements" : [ "cryptography==2.1.3",
"PyJWT==1.5.3" ]
}
Minimal Lambda execution role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1507151548000",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::my-s3-bucket/package-jwt.tar.gz"
]
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
"""
from subprocess import check_output
import uuid
import boto3
DEBUG_OUT_FILE = "/tmp/debug.txt"
S3 = boto3.resource('s3')
def lambda_handler(event, context):
"""
"""
requirements = event.get('requirements', [])
prefix = event.get('prefix', 'myPackage')
saveToS3Bucket = event.get('saveToS3Bucket', None)
saveToS3Key = event.get('saveToS3Key', None)
location = "%s_%s" % (prefix, uuid.uuid4())
destinationPath = '/tmp/%s' % location
tarFileName = '/tmp/%s.tar.gz' % location
for req in requirements:
_exec(['pip', 'install', req, '-t', destinationPath])
_exec(['tar', 'czvf', tarFileName, destinationPath])
_persist_file_to_s3(tarFileName, saveToS3Bucket, saveToS3Key)
return 'done!'
def _exec(statements):
if statements and type(statements) == list:
with open(DEBUG_OUT_FILE, "a") as f:
try:
f.write("n$ %s n" % " ".join(statements))
rv = check_output(statements).decode("utf8")
f.write(rv)
print(rv)
except Exception as ex:
print(ex)
f.write(str(ex))
def _persist_file_to_s3(filePathToUpload, s3Bucket, s3Key):
if filePathToUpload and s3Bucket and s3Key:
S3.meta.client.upload_file(filePathToUpload, s3Bucket, s3Key)
@joarleymoraes答案是正确的。
每个 Lambda实例都是从 Amazon Linux AMI 创建的容器。 pyodbc 需要一些原生库才能工作,而这些库在 Lambda 容器中默认不存在。因此,为了使事情正常工作,您需要确保 Lambda 环境除了包含 pyodbc 和您的函数代码之外,还包括这些本机库。
请参阅 https://medium.com/@narayan.anurag/breaking-the-ice-between-aws-lambda-pyodbc-6f53d5e2bd26 以了解有关问题和解决方案的更多信息。
我通过将 pyodbc git 包添加为 lambda 层并将 python 版本设置为 3.7 来解决此问题示例代码
conn = pyodbc.connect("DRIVER={0};SERVER={1};DATABASE={2};UID={3};PWD={4}".format(driver, server, database, username, password))
您可以从 GIT 下载 pyodbc 层https://github.com/karthigces/lambda_layers