No module named 'psycopg2._psycopg': ModuleNotFoundError in AWS Lambda
Asked Answered
B

14

43

I have created a deployment package for AWS Lambda with my python file and the dependencies including sqlalchemy and psycopg2. The code works perfectly in accessing the DB locally. But when I imported this zip file, I am getting the following error.

No module named 'psycopg2._psycopg': ModuleNotFoundError

The stack trace of the error is,

{
  "errorMessage": "No module named 'psycopg2._psycopg'",
  "errorType": "ModuleNotFoundError",
  "stackTrace": [
    [
      "/var/task/DBAccessLamdaHandler.py",
      50,
      "lambda_handler",
      "engine = create_engine(rds_host)"
    ],
    [
      "/var/task/sqlalchemy/engine/__init__.py",
      387,
      "create_engine",
      "return strategy.create(*args, **kwargs)"
    ],
    [
      "/var/task/sqlalchemy/engine/strategies.py",
      80,
      "create",
      "dbapi = dialect_cls.dbapi(**dbapi_args)"
    ],
    [
      "/var/task/sqlalchemy/dialects/postgresql/psycopg2.py",
      554,
      "dbapi",
      "import psycopg2"
    ],
    [
      "/var/task/psycopg2/__init__.py",
      50,
      "<module>",
      "from psycopg2._psycopg import (                     # noqa"
    ]
  ]
}

Any help is appreciable

Bullfight answered 30/6, 2017 at 22:20 Comment(2)
See github.com/jkehler/awslambda-psycopg2.Fond
You don't need to build it from scratch. The repo includes a pre-built package in the psycopg2 folder that you can simply include in the ZIP file that you're going to upload to Lambda (allegedly, I haven't actually used it).Fond
F
39

The AWS Lambda runtime environment doesn't include the PostgreSQL libraries so you need to include them within your AWS Lambda upload.

One way to do this is to get them from the jkehler/awslambda-psycopg2 repo at GitHub. Note that you don't need to build this project from scratch as the repo includes a pre-built package in the psycopg2 folder that you can simply include in your Lambda upload.

Fond answered 1/7, 2017 at 14:18 Comment(8)
This helps. Thank youJana
How would this solution work with the serverless framework where packages are installed from the requirmets.txt file?Bayne
@Bayne Take a look at github.com/UnitedIncome/serverless-python-requirementsFond
I've included this library like so however it is still not working. Something I'm going wrong?Dote
@Bayne were you able to solve this I am facing the same issue.Gladiatorial
@ankushreddy not yet.. we run it in an EC2 for now but planning to move it to Lambda soon... after I figure this issue out.Bayne
For anyone working with CloudFormation + CodeBuild the following two lines in buildspec.yml worked like a charm: - git clone https://github.com/a-j/awslambda-psycopg2.git && cd awslambda-psycopg2 && git checkout python-3.8-libraries and - cp -r awslambda-psycopg2/psycopg2-3.8 ./src && mv ./src/psycopg2-3.8 ./src/psycopg2Doloresdolorimetry
If you are going to psycopg2-3.6 (- 3.9), do not forget to rename _psycopg.cpython-39-x86_64-linux-gnu.so to _psycopg.soExpressage
V
17

The psycopg2 build library from jkehler/awslambda-psycopg2 was built for python 3.6 and make sure that while uploading your code to AWS lambda, select Python Runtime environment as 3.6, and it should work. I banged my head on this for a full day and then when i changed to 3.6, the import error just vanished.

If you are going to attempt to build it yourself, remember that you must build on a machine or VM with the same architecture as your target at AWS.

Virgulate answered 7/5, 2019 at 15:19 Comment(3)
Thanks Nikhil, but I tried this and it didn't work on p3.6, could you please help in detail?Nardone
@ganeshdeshmukh It work with me on python 3.7. I simply copied the whole folder for python 3.7, rename it to psycopg2, and zip it with my lambda function file. After uploading the zipped file to aws lambda, it worked as expected. I suppose the procedure for python 3.6 should be similar.Alissaalistair
It work with me on python 3.6. I have followed the same procedure as mentioned by @FanchenBaoRhythmandblues
E
13

Like other answers, psycopg2-binary worked fine for python3.9 (it looks like other package awslambda-psycopg2 was only available for python3.6).

But, if you run on MacOs before sending to aws lambda, you must specify the platform to your pip install like this:

pip3.9 install --platform=manylinux1_x86_64 --only-binary=:all: psycopg2-binary
Entablement answered 1/4, 2022 at 13:58 Comment(7)
This is the answer. Many thanks. Your answer and @viru s answer make really sense.Train
This didn't work for me, as pip doesn't appear to support the platform option on MacOS. I just wrote up my solution on Medium You need to follow the AWS Guide to build the psycopg-binary2, and do so in a Docker container The two supported manylinux architectures for Lambda Layers are manylinux2014_x86_64 for AMD64 and manylinux2014_aarch64 for ARM64.Nevers
@therightstuff: it looks like the --target=. option is now mandatory, but it works on macEntablement
@VincentJ I'm on Ventura 13.4.1, and it doesn't work for me. I wouldn't have ever suspected that to be the problem, but then I read "Note: macOS --platform tags don't work" in the AWS Guide. When I used exactly the same command I'd been trying from within a Docker container, it did the job.Nevers
@Nevers aws note is ambiguous but I understand that only manylinux1_x86_64 tag work, not macos nor windows tags. It clearly worked before, but I cannot retest right now I don't have this env anymore.Entablement
@VincentJ You're absolutely right! I guess i need to post a retraction - I don't know what I was doing differently before but I just got it built and deployed successfully without Docker. Thanks!Nevers
For python3.12 this worked: pip install --platform=manylinux2014_x86_64 --only-binary=:all: --target=./python psycopg2-binaryHullo
C
8

Latest as of 26/MAR/2020

I was skeptical about depending on a third-party library for my production code. On research the following works,

The issue happens only when the packages are built from MAC OS.

I can confirm today that the issue is fixed when I build the package from Centos 7 ( AWS AMI )

The following is my approach

requirement.txt

psycopg2-binary==2.8.4

Build process

pip install -r requirements.txt --target .

Lambda code is in the root directory

+-- lambda_function.py
+-- psycopg2
    +-- psycopg2 files

Zip the directory and test the code in lambda works.

The only additional step is to build the package in Linux env instead of macOS using the Docker container. An example can be found here: Deploy AWS Amplify Python Lambda from macOS with Docker

Cocotte answered 26/3, 2020 at 20:52 Comment(2)
How is this related to the AWS Lambda runtime? Packages are installed by pip on the aws/codebuild/standard:2.0 imageDoloresdolorimetry
Python runtime checks for the local library first. Give this a shot - works for me in production till dateCocotte
C
7

The psycopg2 python package requires Postgres libraries which is missing in AMI used by the AWS Lambda function.

The easiest solution is to use a pre-compiled package aws-psycopg2 which has the required libraries. The package is present in the PyPi repository.

pip install aws-psycopg2

After this, just do the import of psycopg2 as usual in your program. Sample import is given below.

import psycopg2 With this package, my Lambda function started working perfectly.

Chic answered 12/4, 2023 at 7:33 Comment(2)
Thank you I did not know aws-psycopg2 existed. I swear I hate working with Amazon Linux sometimesPelorus
This works well and is the fastest way to get a aws-sam lambda working with Postgresql. Thanks!Florinda
T
5

Thanks to AWS Lambda Layers we can include a ready compiled psycopg2 layer for our selected Python versions directly to our Lambda function. Please use the version you need from this Github repo. Be careful to use the correct Python version and Region in Lambda and layer creation.

Trotline answered 23/5, 2022 at 17:12 Comment(1)
This makes my life easier.. LOL ! Thanks !!Hamhung
Q
4

I have faced a similar issue. I tried to create the layers using AWS Cloud shell it worked with Python3.8. But failed in Python3.9 though.

Please change the region name as per your AWS Region

sudo amazon-linux-extras install python3.8

curl -O https://bootstrap.pypa.io/get-pip.py

python3.8 get-pip.py --user

mkdir python

python3.8 -m pip install --platform=manylinux1_x86_64 --only-binary=:all: pandas numpy pymysql psycopg2-binary SQLAlchemy -t python/

zip -r layer.zip python

aws lambda publish-layer-version \
 --layer-name mics-layer \
 --description "Pandas Numpy psycopg2-binary SQLAlchemy pymysql" \
 --zip-file fileb://layer.zip \
 --compatible-runtimes python3.8 python3.9 \
 --region eu-west-1
Quitt answered 20/9, 2022 at 11:47 Comment(0)
R
2

For Windows (Looks like in any OS which is not build on Amazon AMI or Centos), the easiest fix is to use

psycopg2 Python Library for AWS Lambda

which you can find https://github.com/jkehler/awslambda-psycopg2

Ridings answered 14/5, 2020 at 13:28 Comment(0)
S
1

I've had issues getting SQLAlchemy to run on AWS Lambda despite the fact that I have tried multiple psycopg2 versions, but what eventually solved it for me was to use an older Python version. I went from Python 3.9 to 3.7 and it was finally able to run (Using psycopg2-binary 2.8.4, but I didn't try other versions or the none binary version with 3.7)

Subway answered 7/5, 2022 at 10:19 Comment(0)
N
1

I just wrote up my solution to this on Medium, a lot of the suggestions here didn't work for me and one of the main reasons is that pip won't let you target a platform architecture on MacOS! - EDIT: article updated with a retraction on that point, you can indeed build on MacOS.

In short, the most straightforward method (in my opinion) is to follow the AWS Guide to build the psycopg-binary2 (or pyscopg-binary, if you're using sqlalchemy v1), doing so in a Docker container if you're using a Mac.

The two supported manylinux architectures for Lambda Layers are manylinux2014_x86_64 for AMD64 and manylinux2014_aarch64 for ARM64.

Nevers answered 27/7, 2023 at 5:56 Comment(0)
W
1

Honestly, the best way is just to create your own lambda image. I am done struggling to make this work.

Follow this tutorial: https://docs.aws.amazon.com/lambda/latest/dg/python-image.html#python-image-clients

Here's what worked for me:

# Define custom function directory
ARG FUNCTION_DIR="/function"

FROM python:3.10 AS build-image

# Include global arg in this stage of the build
ARG FUNCTION_DIR

# Copy function code
RUN mkdir -p ${FUNCTION_DIR}
COPY . ${FUNCTION_DIR}

# Install the function's dependencies
RUN pip install \
    --target ${FUNCTION_DIR} \
        awslambdaric

# Use a slim version of the base Python image to reduce the final image size
FROM python:3.10-slim

# Include global arg in this stage of the build
ARG FUNCTION_DIR
# Set working directory to function root directory
WORKDIR ${FUNCTION_DIR}

# Copy in the built dependencies
COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}

RUN apt-get update \
  && apt-get -y install gcc python3-dev libpcre3 libpcre3-dev libpq-dev
RUN pip3 install -r psycopg2 -t .


# Set runtime interface client as default command for the container runtime
ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ]
# Pass the name of the function handler as an argument to the runtime
CMD ["migration_lambda.handler"]
Waadt answered 9/11, 2023 at 15:49 Comment(0)
B
0

instead of using psycopg2, try using pg8000 in command prompt go the directory that you are currently working(example F:\example) pip install pg8000 -t. (-t. is for installing pg8000 in the directory that you are working)

// handler.py import pg8000

database=''
host=''
port=''
user=''
password=''
conn = pg8000.connect(database=database, host=host, port=port, user=user, 
password=password)

def lambda_function(event, context):
   .
   .
   .

after writing your code zip the code and upload in your aws lambda.

It worked for me!!!

Boulder answered 10/9, 2020 at 6:59 Comment(0)
K
0

If you are using CDK you can use SQLAlchemy on AWS Lambda by bundling with Docker and providing the right pip install command:

Python 3.8.

    sqlachemy_layer = lambda_.LayerVersion(
        scope=self,
        id=LAYERS_SQLALCHEMY_LAYER,
        layer_version_name=LAYERS_SQLALCHEMY_LAYER,
        code=lambda_.Code.from_asset(
            str(pathlib.Path(__file__).parent.joinpath("dependencies").resolve()),
            bundling=BundlingOptions(
                image=lambda_.Runtime.PYTHON_3_8.bundling_image,
                command=[
                    "bash", "-c",
                    "pip install -r requirements-sqlalchemy.txt -t /asset-output/python && cp -au . /asset-output/python",
                ]
            )
        ),
        compatible_runtimes=[
            lambda_.Runtime.PYTHON_3_8,
        ],
    )

Python 3.9

    sqlachemy_layer = lambda_.LayerVersion(
        scope=self,
        id=LAYERS_SQLALCHEMY_LAYER,
        layer_version_name=LAYERS_SQLALCHEMY_LAYER,
        code=lambda_.Code.from_asset(
            str(pathlib.Path(__file__).parent.joinpath("dependencies").resolve()),
            bundling=BundlingOptions(
                image=lambda_.Runtime.PYTHON_3_9.bundling_image,
                command=[
                    "bash", "-c",
                    "pip3.9 install --platform=manylinux1_x86_64 --only-binary=:all: -r requirements-sqlalchemy.txt -t /asset-output/python && cp -au . /asset-output/python",
                ]
            )
        ),
        compatible_runtimes=[
            lambda_.Runtime.PYTHON_3_9,
        ],
    )

The requirements-sqlalchemy.txt:

psycopg2-binary
sqlalchemy

And the file structure:

  • dependencies/
    • requirements-sqlalchemy.txt
  • my_stack.py
Kaunas answered 28/1, 2023 at 16:56 Comment(0)
C
0

In my case I get this error because I build the package with python 3.10 and I was executing the lambda with runtime python 3.11. After change the runtime lambda the error was resolved.

Culet answered 13/7 at 0:29 Comment(1)
This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. To get notified when this question gets new answers, you can follow this question. Once you have enough reputation, you can also add a bounty to draw more attention to this question. - From ReviewWore

© 2022 - 2024 — McMap. All rights reserved.