【问题标题】:Unable to use pyodbc with aws lambda and API Gateway无法将 pyodbc 与 aws lambda 和 API Gateway 一起使用
【发布时间】:2018-06-09 12:14:32
【问题描述】:

我正在尝试使用利用 pyodbc python 包的 APi Gateway 构建 AWS Lambda 函数。我已按照文档中提到的步骤进行操作。当我测试运行 Lambda 函数时,我不断收到以下错误 Unable to import module 'app': libodbc.so.2: cannot open shared object file: No such file or directory

任何帮助表示赞赏。当我使用 Chalice 部署我的包时,我遇到了同样的错误。看来我可能需要安装 unixodbc-dev。知道如何通过 AWS Lambda 做到这一点吗?

【问题讨论】:

    标签: python amazon-web-services aws-lambda chalice


    【解决方案1】:

    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

    【讨论】:

    • 感谢您提供的信息。我在链接上没有看到 pyodbc 包
    • 那恐怕你得在 Amazon Linux 机器上构建它:docs.aws.amazon.com/lambda/latest/dg/…
    • 我创建了一个 Amazon Linux EC2 实例并生成了库,但它仍然无法正常工作
    • 我也是。创建了 Amazon Linux EC2 并执行了“pip3 install pyodbc -t。”,但仍然没有用。
    【解决方案2】:

    尝试运行此脚本以将依赖项收集到 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)
    

    【讨论】:

      【解决方案3】:

      首先,使用yum install unixODBC unixODBC-devel 安装unixODBCunixODBC-devel 软件包。此步骤将安装 pyodbc 模块所需的一切。

      您缺少的库位于您的 Amazon Linux 实例上的 /usr/lib64 文件夹中。 将库复制到 python 项目的根文件夹(libodbc.so.2 只是一个符号链接,请确保复制符号链接和库本身,如所列):libodbc.solibodbc.so.2libodbc.so.2.0.0

      【讨论】:

        【解决方案4】:

        只需从此处解压缩此文件 - 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

        【讨论】:

          【解决方案5】:

          @joarleymoraes answer 是正确的。

          后台的每个 Lambda 实例都是从 Amazon Linux AMI 创建的容器。 pyodbc 需要一些本机库才能工作,这些库默认情况下不存在于 Lambda 容器中。因此,为了让事情顺利进行,您需要确保 Lambda 环境除了 pyodbc 和您的函数代码之外还包括这些原生库。

          请参阅https://medium.com/@narayan.anurag/breaking-the-ice-between-aws-lambda-pyodbc-6f53d5e2bd26 以了解有关问题和解决方案的更多信息。

          【讨论】:

            【解决方案6】:

            我通过添加 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

            【讨论】:

              猜你喜欢
              • 2018-02-16
              • 2018-12-25
              • 2016-08-11
              • 2023-04-08
              • 1970-01-01
              • 2019-12-12
              • 2017-12-07
              • 2017-08-24
              • 1970-01-01
              相关资源
              最近更新 更多