简体   繁体   English

同一服务器上多个版本的 Sqlite3 for Python

[英]Multiple versions of Sqlite3 for Python on the same server

On a Linux server, I have some Python scripts using the built-in sqlite3 module (+ some Sqlite extensions built from source, as detailed in Upgrade Python's sqlite3 on Debian ).在 Linux 服务器上,我有一些 Python 脚本使用内置的sqlite3模块(+ 一些从源代码构建的 Sqlite 扩展,如在 Debian 上升级 Python 的 sqlite3 中所述)。

For another Python script, I need a newer version of the Sqlite shared library than the one I already have on the system.对于另一个 Python 脚本,我需要一个比系统上已有的更新版本的 Sqlite 共享库。 Reason: I need Sqlite higher than 3.25.0 for Window Functions .原因:我需要 Sqlite高于 3.25.0 的 Window Functions

If I install it from source here and do make and make install , it will probably overwrite previous versions of this library on the server, and could potentially break other OS tools using it.如果我从这里从源代码安装它并执行makemake install ,它可能会覆盖服务器上该库的先前版本,并且可能会破坏使用它的其他操作系统工具。

How do you handle the general problem of having multiple versions of the Sqlite shared library?您如何处理拥有多个版本的 Sqlite 共享库的一般问题?

I don't think Python virtual environments can be used for this context, or would it be possible?我不认为 Python 虚拟环境可用于此上下文,或者有可能吗?

Note: pip3 install --upgrade sqlite3 does not exist: we cannot upgrade Python's built-in sqlite3 package like this.注意: pip3 install --upgrade sqlite3不存在:我们不能像这样升级 Python 的内置sqlite3包。 And by the way we probably should not, since it could break some OS tools using Python + sqlite3.顺便说一句,我们可能不应该这样做,因为它可能会破坏一些使用 Python + sqlite3 的操作系统工具。

This is very tricky and will need a little code change in your scripts.非常棘手,需要在脚本中进行一些代码更改。

What to do:该怎么办:

  • First, check the sqlite3 library version included with python just in case:首先,检查包含在 python 中的 sqlite3版本以防万一:

     python -c "import sqlite3; print(sqlite3.connect(':memory:').execute('SELECT sqlite_version();').fetchall())

    In my computer (python 3.8, windows) the output is [('3.35.5',)] which means python has the sqlite 3.35.5 library.在我的电脑(python 3.8,windows)中,输出是[('3.35.5',)]这意味着 python 有 sqlite 3.35.5 库。 I have no sqlite installed in my system: this is the library that comes with python3.8.我已经没有源码安装在我的系统:这是一个带有python3.8库。

  • IF your python sqlite3 library is not the one you need :-( you have an alternative: you can use the pysqlite3 instead of the sqlite3 standard library. In this case:如果您的 python sqlite3 库不是您需要的 :-( 您有另一种选择:您可以使用pysqlite3而不是sqlite3标准库。在这种情况下:

    1. You'll need to build the pysqlite3 library by yourself using the Sqlite3 'amalgamation' that matches the version you want to use (more on later).您需要使用与您要使用的版本相匹配的 Sqlite3“合并”自行构建 pysqlite3 库(稍后会详细介绍)。
    2. You'll need to install the library, and...您需要安装该库,然后...
    3. You will need to change your python script imports import pysqlite3 as sqlite3 # instead of sqlite3您将需要更改您的 python 脚本导入import pysqlite3 as sqlite3 # instead of sqlite3

Ok, what is the 'amalgamation` and how to build pysqlite3?好的,什么是“合并”以及如何构建 pysqlite3?

The amalgamation is the whole sqlite3 library in just one .c file (with the sqlite3.h file).合并是一个 .c 文件(带有 sqlite3.h 文件)中的整个 sqlite3 库。 You can get it from the sqlite3 download page: sqlite3.36 amalgamation .您可以从 sqlite3 下载页面获取它: sqlite3.36 amalgamation

Once you have the amalgamation, follow the instructions to build statically pysqlite3 , and install the package.完成合并后,按照说明静态构建 pysqlite3 ,并安装包。

Now you can use pysqlite3 in your code.现在您可以在代码中使用 pysqlite3。

If you want 2 different version of sqlite3 (python3) on 2 different environments, you can do that.如果您想在 2 个不同的环境中使用 2 个不同版本的 sqlite3 (python3),您可以这样做。

Since you mentioned that sqlite3 is part of the std library, it seems like you can try the pysqlite3 package instead.由于您提到 sqlite3 是 std 库的一部分,因此您似乎可以尝试使用 pysqlite3 包。

If you can't run pip, run the following command first.如果无法运行pip,请先运行以下命令。

sudo apt install python3-pip

Then,然后,

pip install virtualenv

python3 -m venv sqlitev1 #(whatever name you want)
source sqlitev1/bin/activate
pip install pysqlite3==0.4.4 #(this can be whatever version u want)
source deactivate

python3 -m venv sqlitev2 #(whatever name you want)
source sqlitev2/bin/activate
pip install pysqlite3==0.4.4 #(this can be whatever version u want)
source deactivate

Now you have 2 python environments, sqlitev1 and sqlitev2, with 2 different version of sqlite3.现在您有 2 个 python 环境,sqlitev1 和 sqlitev2,以及 2 个不同版本的 sqlite3。

If you want a different version of Sqlite than that installed with your distro, and a Python that uses that version, then you could如果你想要一个不同于你的发行版安装的 Sqlite 版本,以及一个使用该版本的 Python,那么你可以

  1. Compile sqlite to an alternative location将 sqlite 编译到其他位置
  2. Compile Python to a different location, and point it to the custom Sqlite installation.将 Python 编译到不同的位置,并将其指向自定义 Sqlite 安装。

The "pointing" is covered in the accepted answer to this question . “指向”包含在此问题的已接受答案中。 The question body itself shows how you might compile sqlite to a custom location.问题正文本身显示了如何将 sqlite 编译到自定义位置。

The other answer to that question proposes setting the LD_LIBRARY_PATH environment variable to the directory containing the custom sqlite build to avoid having to compile Python.该问题的另一个答案建议将LD_LIBRARY_PATH环境变量设置为包含自定义 sqlite 构建的目录,以避免编译 Python。 This might work with a virtualenv (it could be set in the preactive hook, for example).这可能适用于 virtualenv(例如,它可以在 preactive 挂钩中设置)。

See also也可以看看

Another approach would be to compile pysqlite3 in a virtualenv over the custom sqlite build.另一种方法是通过自定义 sqlite 构建在 virtualenv 中编译 pysqlite3。 You can read about this in this blog post (I won't copy the details as it isn't clear what licence is used by the blog).您可以在这篇博文中阅读相关内容(我不会复制详细信息,因为不清楚该博客使用了什么许可证)。

It might be super hacky but you can make the new version of sqlite and then make sure that the path pointing to the new version is on the pythonpath environment before the built in one.它可能是超级hacky,但您可以制作新版本的sqlite,然后确保指向新版本的路径在内置路径之前位于pythonpath环境中。 Python will scan the python path from first to last to find an import, so the new version first in the python path for the processes that want the new version and then exclude that path with the old processes that need the built in one. Python 会从头到尾扫描 python 路径以查找导入,因此新版本首先在需要新版本的进程的 python 路径中,然后使用需要内置的旧进程排除该路径。 You can accomplish this with a bash script that loads the env and then runs the python process for the new services.您可以使用 bash 脚本来完成此操作,该脚本加载 env 然后为新服务运行 python 进程。

Again this is super hacky so last resort.再次,这是超级hacky 所以最后的手段。

Why not take out [SQLite] separately and put it in your project, and directly reference the [SQLite] package of the current path in the code.为什么不把【SQLite】单独拿出来放到你的项目中,直接在代码中引用当前路径的【SQLite】包。 Can it meet your needs.能不能满足你的需求。

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

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