我正在尝试将 SQLite 版本更新到 3.24 或更高版本,以便 Python 应用程序可以使用新的“UPSERT”查询。我尝试了几个小时,但收效甚微;它拒绝更新过去3.22
。
我曾尝试过:
使用 apt 安装并重新安装 sqlite / libsqlite3-dev(以及其各个版本)
从启动板下载软件包(例如 https://launchpad.net/ubuntu/+source/sqlite3/3.26.0-2)并尝试安装它们
使用 Python pip 尝试更新 sqlite3
添加一些 PPA 存储库,尝试从那里获取它
从谷歌找到的其他各种建议
我还没尝试过的:
- 从源代码构建 SQLite(这对我来说是最后的手段)
是否可以在 Ubuntu 18.04 上安装 SQLite 3.24+ 版本?如果是这样,那么从源代码构建是唯一的方法吗?还是有一种简单的方法可以通过 apt (或类似方法)获取较新的版本?
答案1
以下是一些选项:
Docker
这是 docker 的实际用例。没有包含最新 sqlite 的官方 Docker 镜像 - 但很容易制作一个:
$ mkdir sqlite333 && cd sqlite333
$ cat > Dockerfile
FROM ubuntu:groovy
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get -yq --no-install-recommends install sqlite3 python3 && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
WORKDIR /root
ENTRYPOINT python3.8 -c "import sqlite3; print(sqlite3.sqlite_version)"
按CtrlD保存,然后:
$ docker build -t sqlite333 .
$ docker run --rm -ti sqlite333
3.33.0
要运行现有的应用程序,只需绑定挂载它:
docker run --rm -ti -v /path/to/myapp:/tmp sqlite333 /tmp/myapp.py
或者您可以将其与 Dockerfile 一起复制到目录中,然后它的副本将被放置在实际的图像中 - 但每当您进行更改时,您都需要重建图像。
如果有官方 Sqlite 镜像使用正确的版本,如果你已经安装并可以运行 Docker,那么你可以使用任何版本的 SQLite 和任何其他版本,整齐地打包例如(来自https://hub.docker.com/r/nouchka/sqlite3)
docker run --rm -ti -v `pwd`:/tmp nouchka/sqlite3 /tmp/myapp.py
这会将当前目录挂载到 docker 镜像中的 /tmp 中,并运行从以下位置构建的镜像:这个Dockerfile- 您可以轻松修改它以安装 Python,并运行您喜欢的任何命令。
前门(社区)方法
你可以强制安装其他发行版或版本使用的.deb文件,这些发行版或版本使用相同的C库。我通常在 Distrowatch 上搜索以找到这些- 但是除了标准 C 库版本之外,还可能存在其他意外的依赖问题,因此从长远来看,您的“快速修复”可能会变得不那么快,甚至彻底破坏您的操作系统的某些部分。
正确的做法是自愿花时间更新官方仓库 - 这样,所有安全性和兼容性问题都将有最佳方式找到正确的渠道,并且您有最大的机会寻求社区的帮助来维护未来的发展。起点是联系当前的 Ubuntu SQLite 软件包维护者,了解您可以做些什么来帮助使其保持最新状态。https://launchpad.net/ubuntu/+source/sqlite3(3.33 实际上是最新 Ubuntu 的一部分,这就是上述 Dockerfile 搭载的原因)这个初始列表显示了 20 多个相关或依赖的软件包,暗示了旧版本可能滞后的原因:https://packages.ubuntu.com/search?keywords=sqlite3
从源代码编译
从源代码编译也不是那么麻烦 - 如果你已经掌握了步骤 - 那么让我们来测试一下 SQLite 的“小巧、快速、可靠”的名声,从https://www.sqlite.org/download.html:
$ wget https://www.sqlite.org/2020/sqlite-autoconf-3330000.tar.gz
$ tar -zxvf sqlite-autoconf-3330000.tar.gz
$ cd sqlite-autoconf-3330000/
$ ./configure
$ make -j4
但这完全回答了你提出的问题。你真正的问题是:
我可以在 Ubuntu 18.04 下安装 SQlite 3.33 for Python 吗?
编辑:Python 确实使用系统 SQLite - 因此按照上述方法编译后,将其安装在 /usr/local 下,理论上您应该能够告诉它使用带有 LD_RUN_PATH 环境变量的特定 SQLite,如下所示 - 但它不起作用:
$ sudo PREFIX=/usr/local make install
通常会使用新的 SQLite:
$ LD_RUN_PATH=/usr/local/lib python3
但似乎 SQLite 或 Python3 还有更多功能,因为仅仅这些还不够 - 如果你在系统范围内安装新版本,它可能会起作用(sudo PREFIX=/usr make install
),它可能会起作用 - 但不建议这样做,因为它可能会破坏与其他系统应用程序的兼容性并破坏系统依赖性,并且您的操作系统可能会在更新时覆盖它 - 您可以参考http://charlesleifer.com/blog/compiling-sqlite-for-use-with-python-applications/以获得更详细的说明,但没有必要,因为我已经复制了下面的要点。
考虑到这一点,docker 方法似乎不仅是一种可扩展且可维护的快速修复方法,而且实际上是首选方法 - 经过仔细检查,可以清楚地发现 SQLite 实际上与主 Python 代码库集成得更紧密,唯一的选择就是编译自己的Python 包如下所示。
另一个解决方案:编译 Python
所以你真正想做的是编译你自己的 Python 副本。
我很惊讶,即使是在我性能不足的笔记本电脑上,编译速度也如此之快。上面链接的指南非常详细,所以我不会重复任何内容,但这里只介绍主要步骤 - 简化:
# Follow the steps copied above to compile SQLite 3.33 - and then after the make, do:
$ sudo PREFIX=/usr/local make install
# Then compile Python
$ sudo apt-get build-dep python3.6 # thanks Ubuntu community!
$ git clone --depth=1 https://github.com/python/cpython
$ cd cpython
$ LD_RUN_PATH=/usr/local/lib ./configure CPPFLAGS="-I/usr/local/include/sqlite3" #updated
$ make -s -j4
# sudo PREFIX=/usr/local make install # if you like, which will install it in /usr/local/bin
# but you can just run it directly from the source directory too
这将为你提供一个支持 SQlite 3.33 的 Python 二进制版本(或你在 /usr/local 下安装的任何版本),你可以将其复制或打包并复制,或者打包成 deb并复制,或打包到你自己的 PPA 中进行分发和 apt 安装。或者如果有人已经这样做了,你可以在 Ubuntu 启动板上搜索它。
编辑:已经测试并正常运行。在没有 LD_RUN_PATH 环境变量的情况下测试上述内容后,注意到它仍然使用发行版本(在本例中为 3.22),很明显它没有被编译 -只是编译了它应该使用的库的路径,就像这样编译时一样。因此,重新编译 Python 可能没有必要,只需在系统范围内安装一个新的 SQLite - 覆盖 OS 打包版本 - 考虑到打包版本可能会在更新时覆盖它,或者删除打包版本可能会破坏依赖于它的其他软件包的 OS 打包,所以这不是一个很好的解决方案。)
(了解所有这些的简单方法就是安装 Slackware 或 Gentoo,这就是我学习的方法。)
其他选择
答案2
正如 Murphy 所说,此版本的 SQLite3 与官方的 Ubuntu 18.04 绑定。我在 Azure 中创建了一个全新的 Ubuntu 18.04.5 LTS,并尝试了几件事,包括安装 Python3.7 和 Python 3.8,SQLite 版本相同。
root@test-011:/home/carles# python3.8 -c "import sqlite3; print(sqlite3.sqlite_version)"
3.22.0
我也尝试下载较新版本的预编译 SQLite 二进制文件,但是都没有用。
我想说的是,即使你让它工作了,将你的程序分发到其他服务器也会很麻烦。我不建议你不使用 LTS 版本提供的官方软件包,因为你不会获得这些软件包的升级和安全补丁。
因此,我认为最简单的方法是安装较新版本的 Ubuntu,或者运行带有较新 Ubuntu 映像版本的 Docker 实例,并在程序中尝试新功能。从源代码构建 SQLite3 对您不起作用,您必须从源代码 + SQLite3 构建 Python3。我的建议是:保持简单。
答案3
目前你可以使用这个 PPA:https://launchpad.net/~fbirlik/+archive/ubuntu/sqlite3并且它可以从此 PPA 安装 Python 3.8,开箱即用:https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa。
答案4
升级到 20.04 即可免费获得 SQLite 3.31*
我确信你可以通过重新编译 SQLite3(和 python3-sqlite)来就地升级它们。我不认为有一个简单的方法(例如 PPA)来实现这一点。然而,这种痛苦和麻烦可能比系统升级或将堆栈移动到 Docker(这是一个好的解决方案)。
您还可以获得 Python 升级...如果您想要 3.8 功能,那么这个升级非常好。
如果你绝对不能—我尊重这一点,我有一些需要单独处理的生产系统 —我认为你确实需要开始考虑将应用程序的 Python 环境与系统的 Python 分离,这样你就可以使用自己编译的版本对其进行升级。或者让 Docker 为你完成这项工作。这意味着应用程序的 Python 环境的基础设施将发生变化,因此一定要先在备份上进行测试。
不要尝试替换系统的 Python 二进制文件,即使使用与较新版本的 SQLite3 绑定的类似版本也是如此。这将以痛苦和悲惨告终,并且可能会有大约 9 部电影讲述你陷入黑暗的危险以及对后代的影响。不过说真的,别管/usr/bin/python{,3}
了。