简体   繁体   English

在 AWS Lambda 上安装更新版本的 sqlite3 以与 Python 一起使用

[英]Install newer version of sqlite3 on AWS Lambda for use with Python

I have a Python script running in a Docker container on AWS Lambda.我有一个 Python 脚本在 AWS Lambda 上的 Docker 容器中运行。 I'm using the recommended AWS image ( public.ecr.aws/lambda/python:3.9 ), which comes with SQLite version 3.7.17 (from 2013.), When I test the container locally on my M1 Mac: I see this:我正在使用推荐的 AWS 映像 ( public.ecr.aws/lambda/python:3.9 ),它附带 SQLite 版本 3.7.17(从 2013 年开始。),当我在 M1 Mac 上本地测试容器时:我看到了这个:

$ docker run --env-file .env --entrypoint bash -ti my-image
bash-4.2# uname -a
Linux e9ed14d35cbe 5.10.104-linuxkit #1 SMP PREEMPT Thu Mar 17 17:05:54 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
bash-4.2# sqlite3 --version
3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668

However, I use newer SQLite features, so I need to find a way to use a newer version of the library.但是,我使用更新的 SQLite 功能,所以我需要找到一种方法来使用更新版本的库。 The most straightforward solution would be to install a binary package as suggested in this answer .最直接的解决方案是按照this answer中的建议安装二进制 package 。 The docs say it should be as simple as installing using pip.文档说它应该像使用 pip 安装一样简单。 Unfortunately, when I attempt to use this approach inside the Docker container, I get this:不幸的是,当我尝试在 Docker 容器中使用这种方法时,我得到了这个:

bash-4.2# pip3 install pysqlite3-binary
ERROR: Could not find a version that satisfies the requirement pysqlite3-binary (from versions: none)
ERROR: No matching distribution found for pysqlite3-binary

And I get the same error when I attempt to install it outside the container using pipenv (which is what I'm actually using for package management):当我尝试使用 pipenv 将它安装在容器外部时,我得到了同样的错误(这是我实际用于 package 管理的内容):

🕙 01:08:24 ❯ pipenv install pysqlite3-binary
Installing pysqlite3-binary...
Error:  An error occurred while installing pysqlite3-binary!
Error text:
ERROR: Could not find a version that satisfies the requirement pysqlite3-binary (from versions: none)
ERROR: No matching distribution found for pysqlite3-binary

✘ Installation Failed

Am I doing something wrong?难道我做错了什么? And if not, how can I get a recent version of SQLite which Python can use in this container?如果没有,我怎样才能获得 Python 可以在这个容器中使用的 SQLite 的最新版本? Do I really need to use a separate build stage in the Dockerfile as suggested here and copy the rpm components into place as laid out here ?我真的需要按照此处的建议在 Dockerfile 中使用单独的构建阶段并将 rpm 组件复制到此处所述的位置吗? That feels like a lot of work for something that many people presumably need to do all the time.对于许多人可能一直需要做的事情,这感觉像是很多工作。


Update: I tried the rpm approach inside the container using version 3.26 from EPEL8 (IIUC) and it failed with a bunch of dependency errors like this:更新:我使用EPEL8 (IIUC) 的 3.26 版在容器内尝试了 rpm 方法,但它失败了,出现了一堆这样的依赖错误:

bash-4.2# curl --output-dir /tmp -sO https://vault.centos.org/centos/8/BaseOS/aarch64/os/Packages/sqlite-3.26.0-15.el8.aarch64.rpm
bash-4.2# yum localinstall /tmp/sqlite-3.26.0-15.el8.aarch64.rpm
Loaded plugins: ovl
Examining /tmp/sqlite-3.26.0-15.el8.aarch64.rpm: sqlite-3.26.0-15.el8.aarch64

# etc.

--> Finished Dependency Resolution
Error: Package: sqlite-3.26.0-15.el8.aarch64 (/sqlite-3.26.0-15.el8.aarch64)
           Requires: libc.so.6(GLIBC_2.28)(64bit)

# Plus 6 other package dependency errors

Error: Package: nss-softokn-3.67.0-3.amzn2.0.1.aarch64 (@amzn2-core)
           Requires: libsqlite3.so.0()(64bit)
           Removing: sqlite-3.7.17-8.amzn2.1.1.aarch64 (@amzn2-core)
               libsqlite3.so.0()(64bit)
           Updated By: sqlite-3.26.0-15.el8.aarch64 (/sqlite-3.26.0-15.el8.aarch64)
               Not found
           Obsoleted By: sqlite-3.26.0-15.el8.aarch64 (/sqlite-3.26.0-15.el8.aarch64)
               Not found
           Available: sqlite-3.7.17-8.amzn2.0.2.aarch64 (amzn2-core)
               libsqlite3.so.0()(64bit)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

When I try --skip-broken , it just skips installing the 3.26 package altogether.当我尝试--skip-broken时,它只是完全跳过安装 3.26 package。


Update 2: I've tried downloading the Python 3.9 wheel from pysqlite3-binary manually.更新 2:我尝试从pysqlite3-binary手动下载 Python 3.9 轮。 However, it looks like that project only produces wheels for x86_64 , not the aarch64 platform ~~which Lambda uses.~~ (This is not correct, see answer.) So presumably that's why pip is not finding it.但是,看起来该项目只为x86_64生产轮子,而不是为 Lambda 使用的aarch64平台。~~(这是不正确的,请参阅答案。)所以大概这就是为什么pip没有找到它的原因。

The problem was that I was running Docker locally to do my testing, on an M1 Mac.问题是我在 M1 Mac 上本地运行 Docker 进行测试。 Hence the aarch64 architecture.因此, aarch64架构。 Lambda does allow you to use ARM, but thankfully it still defaults to x86_64 . Lambda 确实允许您使用 ARM,但幸运的是它仍然默认为x86_64 I confirmed that my Lambda function was running x86_64 , which is what the binary wheel uses, so that's good:我确认我的 Lambda function 正在运行x86_64 ,这是二进制轮使用的,这很好:

在此处输入图像描述

So I needed to do three things:所以我需要做三件事:

  1. Change my Pipfile to conditionally install the binary package only on x86_64:更改我的Pipfile以有条件地仅在 x86_64 上安装二进制 package:

     pysqlite3-binary = { version = "*", platform_machine = "== 'x86_64'" }
  2. Tweak the sqlite import, as described in the original answer :调整 sqlite 导入,如原始答案中所述:

     try: import pysqlite3 as sqlite3 except ModuleNotFoundError: import sqlite3 # for local testing because pysqlite3-binary couldn't be installed on macos print(f"{sqlite3.sqlite_version=}")
  3. Set my Docker container to launch in x86 emulation mode locally.将我的 Docker 容器设置为在本地以 x86 仿真模式启动。

     $ DOCKER_DEFAULT_PLATFORM=linux/amd64 docker build -t my-image. $ DOCKER_DEFAULT_PLATFORM=linux/amd64 docker run -ti my-image

Et, voilà!等等,瞧!

sqlite3.sqlite_version='3.39.2'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM