强制Python放弃本地sqlite3并使用已安装的最新sqlite3版本
我想解决的错误信息是:
AttributeError: 'sqlite3.Connection' 对象没有 'enable_load_extension' 这个属性
我已经通过 'easy_install' 安装了最新的 sqlite3 版本,Python 似乎知道它存在,因为 sqlite3.version_info 显示的是 3.6.13。在这个版本中,Connection 应该有 'enable_load_extension' 这个属性。
我认为发生的情况是,Python 仍然在使用原生的 sqlite3 模块,我猜这个版本是 2.4.1,因为 sqlite3.version(而不是 sqlite3.version_info)显示的是 2.4.1。
我的问题是,如何强制 Python 在所有 sqlite3 调用中使用新的 sqlite3 模块呢?
4 个回答
你需要查看一下你的Python路径,确保你想要的sqlite安装在比内置sqlite更早的目录里。
你可以用下面的命令查看路径:
import sys
print(sys.path)
如果你想知道某个模块是从哪里来的,可以试试下面的命令:
print(sqlite3.__file__)
我在一台装有Python 2.7的Windows电脑上,发现自带的sqlite3版本是3.6.x。通过以下步骤,我成功把它升级到了sqlite 3.7.9。
- 先去下载并解压预编译好的DLL文件(可以在http://www.sqlite.org/download.html找到“sqlite-dll-win32-x86-3070900.zip”)。
- (为了安全起见,最好在这一步关闭所有Python的窗口)然后去到C:\Python27\DLLs,把“sqlite3.dll”这个文件改名为“sqlite3.dll.old”。
- 接着,把下载好的“sqlite3.dll”文件复制到C:\Python27\DLLs这个文件夹里。
- 打开Python的命令行,输入导入sqlite3的命令。
- 最后,检查一下sqlite3.sqlite_version,确认它显示的是'3.7.9'。
sqlite3
在 Python 中的支持可能会让人感到有些困惑。最开始,sqlite
数据库适配器是一个独立的项目,叫做 pysqlite2,但在 Python 2.5 版本中,它被整合进了 Python 的标准库,名字变成了 sqlite3。原来的适配器仍然在作为独立项目继续开发,同时 Python 自带的版本也会定期更新,以保持一致。如果你想使用更新版本的适配器,通常会安装为 pysqlite2
,以避免与标准库中的版本冲突。而且,根据它的构建方式,它可能会链接到不同版本的底层 sqlite3 数据库库。所以一定要确保你正确导入它:
>>> import sqlite3
>>> sqlite3.version_info
(2, 4, 1)
>>> sqlite3.sqlite_version_info
(3, 6, 11)
>>> from pysqlite2 import dbapi2 as sqlite3
>>> sqlite3.version_info
(2, 5, 5)
>>> sqlite3.sqlite_version_info
(3, 6, 18)
version_info
是 sqlite3
(pysqlite2
或内置的 sqlite3
)数据库适配器的版本。sqlite_version_info
是底层 sqlite3
数据库库的版本。
建议使用 from ... import ... as sqlite3
这样写,这样如果你在两个版本之间切换,其他代码就不需要改动。
注意,enable_load_extension
是在 pysqlite2
2.5.0 版本中首次出现的。
编辑: enable_load_extension
在构建适配器时默认是禁用的。要启用它,你可以手动构建 pysqlite2
。以下步骤假设你使用的是 unix
系统,并且当前最新版本是 pysqlite2
2.5.5。
首先,如果你最开始是通过 easy_install
安装的适配器,先运行以下命令卸载它:
$ sudo /path/to/easy_install -m pysqlite # or whatever package name you first used
运行后会有一些输出,包括类似以下的行:
Removing pysqlite 2.5.5 from easy-install.pth file
Using /path/to/site-packages/pysqlite-2.5.5-py2.x-something.egg
使用列出的文件名移除这个包(文件名会根据你的平台和版本有所不同,可能指的是一个文件或一个目录):
$ sudo rm -r /path/to/site-packages/pysqlite-2.5.5-py2.x-something.egg
现在下载并解压 pysqlite-2.5.5
的源代码压缩包:
$ mkdir /tmp/build
$ cd /tmp/build
$ curl http://oss.itsystementwicklung.de/download/pysqlite/2.5/2.5.5/pysqlite-2.5.5.tar.gz | tar xz
$ cd pysqlite-2.5.5
然后编辑 setup.cfg
文件,注释掉 SQLITE_OMIT_LOAD_EXTENSION
指令:
$ ed setup.cfg <<EOF
> /SQLITE_OMIT_LOAD_EXTENSION/s/define=/#define=/
> w
> q
> EOF
由于 sqlite3
的版本非常旧(3.4.0),你还应该使用最新的 sqlite3
库进行构建。这在 pysqlite2
的 setup.py 脚本中很方便:
$ /path/to/python2.x setup.py build_static
这将自动下载最新的 sqlite3 合并源代码,并与最新的静态链接版本的 sqlite3
一起构建适配器。这个步骤可能需要一些时间才能完成。
更新(2015/07/21):根据最新的 pysqlite 2.6.3 提交,你必须自己下载 sqlite 源代码,并将其放在 pysqlite 根文件夹中。
现在,安装适配器:
$ sudo /path/to/python2.x setup.py install
并运行测试:
$ cd # somewhere out of the build directory
$ /path/to/python2.x
>>> from pysqlite2 import test
>>> test.test()
如果测试通过,你就可以开始使用了。
作为额外提示,如果你想要加载扩展的原因是使用 sqlite3
的全文搜索扩展 FTS3
,你会发现它已经包含在静态库中,不需要进一步的操作:
>>> from pysqlite2 import dbapi2 as sqlite3
>>> con = sqlite3.connect(":memory:")
>>> con.execute("create virtual table recipe using fts3(name, ingredients)")
<pysqlite2.dbapi2.Cursor object at 0xca5e0>