Невозможно использовать pyodbc с AWS лямбда и API-шлюзом
Я пытаюсь создать функцию AWS Lambda, используя APi Gateway, который использует пакет pyodbc python. Я следовал за шагами как упомянуто в документации. Я получаю следующее сообщение об ошибке: " Невозможно импортировать модуль" приложение ": libodbc.so.2: невозможно открыть общий объектный файл: нет такого файла или каталога, когда я тестирую, запускаю функцию Lambda.
Любая помощь приветствуется. Я получаю ту же ошибку при развертывании пакета с помощью Chalice. Кажется, может быть, мне нужно установить unixodbc-dev. Есть идеи, как это сделать через AWS Lambda?
6 ответов
Просто распакуйте этот файл отсюда - github - lambda_packages / pyodbc. В нем есть файлы.so.
Теперь упакуйте код Python и файлы.so вместе и загрузите в AWS lambda. Структура папок для справки должна выглядеть следующим образом.
lambda_function.py
libodbc.so.2
pyodbc.so
<name_this_zip>.zip
No subfolders exist
pyodbc использует некоторые родные библиотеки. Поэтому вы не можете просто скопировать содержимое вашего site-packages
к лямбде, так как ваша ОС скорее всего не Amazon Linux.
Поэтому вам нужно установить pyodbc на экземпляр Amazon Linux и использовать сгенерированные библиотеки:
https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html
Или вы можете получить отсюда, если доступно там:
Fisrt, установить unixODBC
а также unixODBC-devel
пакеты, использующие yum install unixODBC unixODBC-devel
, Этот шаг установит все необходимое для модуля pyodbc.
Библиотека, которую вы пропустили, находится в /usr/lib64
Папка на вашем экземпляре Amazon Linux. Скопируйте библиотеку в корневую папку вашего проекта Python (libodbc.so.2 - просто символическая ссылка, убедитесь, что вы скопировали символическую ссылку и саму библиотеку, как указано): libodbc.so
, libodbc.so.2
а также libodbc.so.2.0.0
Я решил это, добавив пакет pyodbc git в качестве лямбда-слоя и установив версию python на образец кода 3.7.
conn = pyodbc.connect("DRIVER={0};SERVER={1};DATABASE={2};UID={3};PWD={4}".format(driver, server, database, username, password))
вы можете скачать слой pyodbc из GIThttps://github.com/karthigces/lambda_layers
Попробуйте запустить этот скрипт, чтобы собрать зависимость в корзину s3, а затем добавить ее в ваш пакет развертывания лямбда-выражений.
"""
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 под капотом представляет собой контейнер, созданный из AMI Amazon Linux. pyodbc нуждается в некоторых собственных библиотеках для работы, которые по умолчанию отсутствуют внутри контейнера Lambda. Итак, чтобы все работало, вам необходимо убедиться, что среда Lambda включает эти собственные библиотеки в дополнение к pyodbc и вашему коду функции.
См. https://medium.com/@narayan.anurag/breaking-the-ice-between-aws-lambda-pyodbc-6f53d5e2bd26, чтобы узнать больше о проблеме и ее решении.