Невозможно использовать pyodbc с aws lambda и API Gateway

Я пытаюсь создать функцию AWS Lambda с использованием шлюза APi, который использует пакет pyodbc python. Я выполнил шаги, указанные в документации. Я продолжаю получать следующую ошибку: Невозможно импортировать модуль «приложение»: libodbc.so.2: невозможно открыть файл общих объектов: нет такого файла или каталога, когда я тестирую запуск функции Lambda.

Любая помощь приветствуется. Я получаю ту же ошибку, когда развертываю свой пакет с помощью Chalice. Возможно, мне нужно установить unixodbc-dev. Есть идеи, как это сделать с помощью AWS Lambda?


person Akshay Saxena    schedule 29.12.2017    source источник


Ответы (5)


pyodbc использует некоторые собственные библиотеки. Следовательно, вы не можете просто скопировать содержимое вашего site-packages в Lambda, поскольку ваша ОС, скорее всего, не Amazon Linux.

Итак, вам нужно установить pyodbc на экземпляр Amazon Linux и использовать сгенерированные библиотеки:

https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html

Или вы можете получить отсюда, если есть там:

https://github.com/Miserlou/lambda-packages

person joarleymoraes    schedule 29.12.2017
comment
Спасибо за эту информацию. Я не вижу пакета pyodbc по ссылке, хотя - person Akshay Saxena; 29.12.2017
comment
Тогда, боюсь, вам придется собрать его на машине Amazon Linux: docs.aws.amazon.com/lambda/latest/dg/ - person joarleymoraes; 30.12.2017
comment
Я создал экземпляр Amazon Linux EC2 и сгенерировал библиотеки, но он по-прежнему не работал - person Joshua Kemmerer; 14.03.2018
comment
Я тоже. Создал Amazon Linux EC2 и выполнил pip3 install pyodbc -t., Но все равно это не сработало. - person Aakash Basu; 11.10.2019

Просто распакуйте этот файл отсюда - github - lambda_packages / pyodbc . В нем есть файлы .so.

Теперь упакуйте код Python и файлы .so вместе и загрузите в AWS lambda. Структура папок для справки должна выглядеть следующим образом.

lambda_function.py
libodbc.so.2
pyodbc.so
<name_this_zip>.zip

No subfolders exist

Изменить: создал слой лямбда и сохранил его для повторного использования. Получите это здесь - https://github.com/kuharan/Lambda-Layers

person Kuharan Bhowmik    schedule 02.05.2020

попробуйте запустить этот сценарий, чтобы собрать зависимость в корзине 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)
person Nicholas    schedule 02.01.2018

Во-первых, установите пакеты 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

person vtuhtan    schedule 19.06.2018

@joarleymoraes ответ правильный.

Каждый инстанс Lambda под капотом представляет собой контейнер, созданный из AMI Amazon Linux. pyodbc нуждается в некоторых собственных библиотеках для работы, которые по умолчанию отсутствуют внутри контейнера Lambda. Итак, чтобы все работало, вам необходимо убедиться, что среда Lambda включает эти собственные библиотеки в дополнение к pyodbc и вашему коду функции.

См. https://medium.com/@narayan.anurag/breaking-the-ice-between-aws-lambda-pyodbc-6f53d5e2bd26, чтобы узнать больше о проблеме и ее решении.

person narayan    schedule 13.10.2020