使用psycopg2和Lambda更新红移(Python)

使用psycopg2和Lambda更新红移(Python),python,amazon-web-services,aws-lambda,amazon-redshift,aws-sdk,Python,Amazon Web Services,Aws Lambda,Amazon Redshift,Aws Sdk,我正在尝试使用python从Lambda函数更新Redshift。为此,我尝试合并两个代码片段。当我分别运行这两个片段时,它们都可以正常工作 从PyDev为Eclipse更新红移 import psycopg2 conn_string = "dbname='name' port='0000' user='name' password='pwd' host='url'" conn = psycopg2.connect(conn_string) cursor = conn.cursor() c

我正在尝试使用python从Lambda函数更新Redshift。为此,我尝试合并两个代码片段。当我分别运行这两个片段时,它们都可以正常工作

  • 从PyDev为Eclipse更新红移

    import psycopg2
    
    conn_string = "dbname='name' port='0000' user='name' password='pwd' host='url'"
    conn = psycopg2.connect(conn_string)
    
    cursor = conn.cursor()
    
    cursor.execute("UPDATE table SET attribute='new'")
    conn.commit()
    cursor.close()
    
  • 接收上传到S3 Bucket的内容(Lambda上提供的预构建模板)

  • 由于这两个部分都起作用,我尝试将它们组合起来,以便在将文件上载到s3时更新红移:

    from __future__ import print_function
    
    import json
    import urllib
    import boto3
    import psycopg2
    
    print('Loading function')
    
    s3 = boto3.client('s3')
    
    
    def lambda_handler(event, context):
        #print("Received event: " + json.dumps(event, indent=2))
    
        # Get the object from the event and show its content type
        bucket = event['Records'][0]['s3']['bucket']['name']
        key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key']).decode('utf8')
    
        conn_string = "dbname='name' port='0000' user='name' password='pwd' host='url'"
    
        conn = psycopg2.connect(conn_string)
    
        cursor = conn.cursor()
    
        cursor.execute("UPDATE table SET attribute='new'")
        conn.commit()
        cursor.close()
    
        try:
            response = s3.get_object(Bucket=bucket, Key=key)
            print("CONTENT TYPE: " + response['Body'].read())
            return response['Body'].read()
        except Exception as e:
            print(e)
            print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
            raise e
    
    因为我使用的是外部库,所以我需要创建一个部署包。我创建了一个新文件夹(lambda_function1)并将.py文件(lambda_function1.py)移动到该文件夹中。我运行以下命令在该文件夹中安装psycopg2:

    pip install psycopg2 -t \lambda_function1
    
    我收到以下反馈:

    Collecting psycopg2
      Using cached psycopg2-2.6.1-cp34-none-win_amd64.whl
    Installing collected packages: psycopg2
    Successfully installed psycopg2-2.6.1 
    
    然后我压缩了目录的内容。并将该zip上传到我的lambda函数。当我将文档上载到函数监视的存储桶时,我在cloudwatch日志中收到以下错误:

    Unable to import module 'lambda_function1': No module named _psycopg 
    
    当我查看库时,唯一名为“\u psycopg”的东西是“\u psycopg.pyd”


    是什么导致了这个问题?当我使用3.4时,Lambda使用Python2.7有关系吗?我在Windows机器上压缩文件内容有关系吗?是否有人能够从lambda成功连接到Redshift

    为了使其正常工作,您需要使用静态链接的
    libpq.so
    库构建
    psycopg2
    。看看这个回购协议。它已经构建了psycopg2包,并说明了如何自己构建它

    回到你的问题:

    是什么导致此问题?

    psycopg2
    需要使用Linux的静态链接库构建一个编译库

    当我使用3.4时,Lambda使用Python 2.7有关系吗?

    是的,lambda只支持2.7版本。只需创建虚拟环境并在其中安装所有必要的软件包

    在Windows计算机上压缩文件内容是否重要?

    只要你压缩的所有库都可以在Linux上运行,它就不会运行

    是否有人能够从lambda成功连接到红移?


    是的。

    为了让它工作,您需要使用静态链接的
    libpq.so
    库构建
    psycopg2
    。看看这个回购协议。它已经构建了psycopg2包,并说明了如何自己构建它

    回到你的问题:

    是什么导致此问题?

    psycopg2
    需要使用Linux的静态链接库构建一个编译库

    当我使用3.4时,Lambda使用Python 2.7有关系吗?

    是的,lambda只支持2.7版本。只需创建虚拟环境并在其中安装所有必要的软件包

    在Windows计算机上压缩文件内容是否重要?

    只要你压缩的所有库都可以在Linux上运行,它就不会运行

    是否有人能够从lambda成功连接到红移?


    是的。

    我刚刚遇到了同样的问题。我无意中发现了另一个答案中提到的相同问题,该答案解释了以下问题:

    由于AWS Lambda在AMI映像中缺少所需的PostgreSQL库,我们需要使用PostgreSQL libpq.so库静态链接libpq库而不是默认的动态链接来编译psycopg2

    这在前面的回答中已经提到,我开始按照说明为自己构建一个带有静态链接PostgreSQL库的psycopg2版本。不过我找到了一个更容易的选择。我在网上注意到:

    通过从PyPI安装psycopg2二进制软件包,您还可以获得独立软件包,不需要编译器或外部库:

    $pip安装psycopg2二进制文件

    二进制软件包是开发和测试的实际选择,但在生产中建议使用从源代码构建的软件包


    当我pip安装了psycopg2二进制软件包并将其包含在requirements.txt文件中时,我能够完美地从lambda函数连接到postgresql数据库。我使用的是我极力推荐的。我意识到psycopg2建议不要在生产中使用二进制版本,但我不认为使用二进制版本与自己编译和静态链接之间有很大区别。如果我错了,请有人纠正我

    我刚刚遇到了同样的问题。我无意中发现了另一个答案中提到的相同问题,该答案解释了以下问题:

    由于AWS Lambda在AMI映像中缺少所需的PostgreSQL库,我们需要使用PostgreSQL libpq.so库静态链接libpq库而不是默认的动态链接来编译psycopg2

    这在前面的回答中已经提到,我开始按照说明为自己构建一个带有静态链接PostgreSQL库的psycopg2版本。不过我找到了一个更容易的选择。我在网上注意到:

    通过从PyPI安装psycopg2二进制软件包,您还可以获得独立软件包,不需要编译器或外部库:

    $pip安装psycopg2二进制文件

    二进制软件包是开发和测试的实际选择,但在生产中建议使用从源代码构建的软件包

    当我pip安装了psycopg2二进制软件包并将其包含在requirements.txt文件中时,我能够完美地从lambda函数连接到postgresql数据库。我使用的是我极力推荐的。我意识到psycopg2建议不要在生产中使用二进制版本,但我不认为使用二进制版本与自己编译和静态链接之间有很大区别。
    Unable to import module 'lambda_function1': No module named _psycopg 
    
    export PKG_DIR="python"
    
    rm -rf ${PKG_DIR} && mkdir -p ${PKG_DIR}
    
    docker run --rm -v $(pwd):/foo -w /foo lambci/lambda:build-python3.6 \
        pip install -r requirements.txt --no-deps -t ${PKG_DIR}
    
    aws-psycopg2