同一台服务器上 Python 的多个版本的 Sqlite3
Multiple versions of Sqlite3 for Python on the same server
在 Linux 服务器上,我有一些使用内置 sqlite3
模块的 Python 脚本(+ 一些从源代码构建的 Sqlite 扩展,详见 ).
对于另一个 Python 脚本,我需要比系统上已有的 更新版本 的 Sqlite 共享库。原因:我需要 Sqlite higher than 3.25.0 for Window Functions.
如果我安装它 from source here 并执行 make
和 make install
,它可能会覆盖服务器上此库的以前版本,并可能破坏其他 OS 使用它的工具。
您如何处理具有多个版本的 Sqlite 共享库的一般问题?
我认为 Python 虚拟环境不能用于这种情况,或者有可能吗?
注意:pip3 install --upgrade sqlite3
不存在:我们不能像这样升级Python的内置sqlite3
包。顺便说一下,我们可能不应该这样做,因为它可能会破坏一些使用 Python + sqlite3.
的 OS 工具
如果你想在 2 个不同的环境中使用 2 个不同版本的 sqlite3 (python3),你可以这样做。
既然你提到 sqlite3 是 std 库的一部分,那么你似乎可以试试 pysqlite3 包。
如果不能运行 pip,运行先执行以下命令。
sudo apt install python3-pip
然后,
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
现在你有 2 个 python 环境,sqlitev1 和 sqlitev2,以及 2 个不同版本的 sqlite3。
它可能超级 hacky,但您可以制作新版本的 sqlite,然后确保指向新版本的路径位于内置版本之前的 pythonpath 环境中。 Python 将从头到尾扫描 python 路径以查找导入,因此新版本首先在 python 路径中用于需要新版本的进程,然后排除该路径需要内置流程的旧流程。您可以使用加载环境的 bash 脚本完成此操作,然后为新服务运行 python 进程。
这又是超级骇人听闻的最后一招。
如果您想要的 Sqlite 版本不同于随您的发行版安装的版本,并且 Python 使用该版本,那么您可以
- 将 sqlite 编译到另一个位置
- 将 Python 编译到不同的位置,并将其指向自定义的 Sqlite 安装。
accepted answer to this question中涵盖了“指向”。问题主体本身显示了如何将 sqlite 编译到自定义位置。
该问题的 other answer 建议将 LD_LIBRARY_PATH
环境变量设置为包含自定义 sqlite 构建的目录以避免必须编译 Python。这可能适用于 virtualenv(例如,它可以在 preactive 挂钩中设置)。
另见
- What is LD_LIBRARY_PATH and how to use it?
- Set LD_LIBRARY_PATH before importing in python
另一种方法是通过自定义 sqlite 构建在 virtualenv 中编译 pysqlite3。您可以在 this blog post 中阅读相关内容(我不会复制详细信息,因为不清楚博客使用的是什么许可证)。
这非常棘手,需要在您的脚本中稍作更改。
要做什么:
首先,检查 python 附带的 sqlite3 library 版本以防万一:
python -c "import sqlite3; print(sqlite3.connect(':memory:').execute('SELECT sqlite_version();').fetchall())
在我的电脑中(python 3.8,windows)输出是 [('3.35.5',)]
这意味着 python 有 sqlite 3.35.5 库。我的系统中没有安装 sqlite:这是 with python3.8.
附带的库
如果您的 python sqlite3 库不是您需要的 :-( 您有另一种选择:您可以使用 pysqlite3 而不是 sqlite3
标准库。在这种情况下:
- 您需要使用与您要使用的版本相匹配的 Sqlite3 'amalgamation' 自行构建 pysqlite3 库(稍后会详细介绍)。
- 您需要安装库,并且...
- 您需要更改 python 脚本导入
import pysqlite3 as sqlite3 # instead of sqlite3
好的,什么是“合并”以及如何构建 pysqlite3?
amalgamation is the whole sqlite3 library in just one .c file (with the sqlite3.h file). You can get it from the sqlite3 download page: sqlite3.36 amalgamation.
完成合并后,按照 instructions to build statically pysqlite3 并安装包。
现在您可以在代码中使用 pysqlite3。
在 Linux 服务器上,我有一些使用内置 sqlite3
模块的 Python 脚本(+ 一些从源代码构建的 Sqlite 扩展,详见
对于另一个 Python 脚本,我需要比系统上已有的 更新版本 的 Sqlite 共享库。原因:我需要 Sqlite higher than 3.25.0 for Window Functions.
如果我安装它 from source here 并执行 make
和 make install
,它可能会覆盖服务器上此库的以前版本,并可能破坏其他 OS 使用它的工具。
您如何处理具有多个版本的 Sqlite 共享库的一般问题?
我认为 Python 虚拟环境不能用于这种情况,或者有可能吗?
注意:pip3 install --upgrade sqlite3
不存在:我们不能像这样升级Python的内置sqlite3
包。顺便说一下,我们可能不应该这样做,因为它可能会破坏一些使用 Python + sqlite3.
如果你想在 2 个不同的环境中使用 2 个不同版本的 sqlite3 (python3),你可以这样做。
既然你提到 sqlite3 是 std 库的一部分,那么你似乎可以试试 pysqlite3 包。
如果不能运行 pip,运行先执行以下命令。
sudo apt install python3-pip
然后,
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
现在你有 2 个 python 环境,sqlitev1 和 sqlitev2,以及 2 个不同版本的 sqlite3。
它可能超级 hacky,但您可以制作新版本的 sqlite,然后确保指向新版本的路径位于内置版本之前的 pythonpath 环境中。 Python 将从头到尾扫描 python 路径以查找导入,因此新版本首先在 python 路径中用于需要新版本的进程,然后排除该路径需要内置流程的旧流程。您可以使用加载环境的 bash 脚本完成此操作,然后为新服务运行 python 进程。
这又是超级骇人听闻的最后一招。
如果您想要的 Sqlite 版本不同于随您的发行版安装的版本,并且 Python 使用该版本,那么您可以
- 将 sqlite 编译到另一个位置
- 将 Python 编译到不同的位置,并将其指向自定义的 Sqlite 安装。
accepted answer to this question中涵盖了“指向”。问题主体本身显示了如何将 sqlite 编译到自定义位置。
该问题的 other answer 建议将 LD_LIBRARY_PATH
环境变量设置为包含自定义 sqlite 构建的目录以避免必须编译 Python。这可能适用于 virtualenv(例如,它可以在 preactive 挂钩中设置)。
另见
- What is LD_LIBRARY_PATH and how to use it?
- Set LD_LIBRARY_PATH before importing in python
另一种方法是通过自定义 sqlite 构建在 virtualenv 中编译 pysqlite3。您可以在 this blog post 中阅读相关内容(我不会复制详细信息,因为不清楚博客使用的是什么许可证)。
这非常棘手,需要在您的脚本中稍作更改。
要做什么:
首先,检查 python 附带的 sqlite3 library 版本以防万一:
python -c "import sqlite3; print(sqlite3.connect(':memory:').execute('SELECT sqlite_version();').fetchall())
在我的电脑中(python 3.8,windows)输出是
附带的库[('3.35.5',)]
这意味着 python 有 sqlite 3.35.5 库。我的系统中没有安装 sqlite:这是 with python3.8.如果您的 python sqlite3 库不是您需要的 :-( 您有另一种选择:您可以使用 pysqlite3 而不是
sqlite3
标准库。在这种情况下:- 您需要使用与您要使用的版本相匹配的 Sqlite3 'amalgamation' 自行构建 pysqlite3 库(稍后会详细介绍)。
- 您需要安装库,并且...
- 您需要更改 python 脚本导入
import pysqlite3 as sqlite3 # instead of sqlite3
好的,什么是“合并”以及如何构建 pysqlite3?
amalgamation is the whole sqlite3 library in just one .c file (with the sqlite3.h file). You can get it from the sqlite3 download page: sqlite3.36 amalgamation.
完成合并后,按照 instructions to build statically pysqlite3 并安装包。
现在您可以在代码中使用 pysqlite3。