Python中Sqlite加载spatialite扩展失败
我正在尝试使用Spatialite的3.0测试版,因为我的电脑是64位的Windows 7。
每当我尝试加载libspatialite-4.dll
时,总是会出现一个让我头疼的错误:sqlite3.OperationalError: 找不到指定的模块。
我尝试过以下几种方法:
- 把
libspatialite-4.dll
和其他所有的dll文件放在同一个文件夹里 - 使用dll文件的完整路径
- 把dll文件的位置添加到
'PATH'
环境变量中 - 在Python代码中把dll文件的位置添加到sys.path属性里
- 把所有dll文件复制到
c:\windows\system32
文件夹里(还重启了电脑) - 把所有dll文件复制到
c:\windows\sysWoW64
文件夹里(也重启了电脑,这个文件夹是给32位dll用的,但我还是试了一下)
我的代码如下:
import sqlite3
conn = sqlite3.connect(":memory:")
conn.enable_load_extension(True)
conn.execute('SELECT load_extension("libspatialite-4.dll")')
注意 - 我也试过完整路径,但还是不行。我记得在Windows XP 32位的时候也遇到过同样的问题。那时候我解决了,但现在想不起来我是怎么做到的 :(
更新
我在32位的Windows 7上测试过这个设置,把所有dll文件放在System32文件夹里是可以工作的。所以,这说明64位的设置可能有问题。是不是我需要另一个版本的MSVC(我觉得Spatialite网站上没有说明需要哪个版本,所以我可能得自己猜 - 我安装的是MSVC2010)?
4 个回答
我最近经历了一场关于pyspatialite 3.0.1的x64构建的噩梦,还有它所有的依赖库。虽然可以完成,但需要一些“调整”才能搞定。
首先,注意这里可能需要的一个解决方法,用于编译spatialite.c的合并文件:
Pyspatialite 3.0.1 问题 #7 评论 #3
其次,我建议你使用MSVC 2008 / SDK 7.0 x64来编译,因为Python 2.7 x64就是用这个编译的。当我用mingw-w64编译依赖库时,遇到了很多麻烦。
iconv(版本1.9.2)和proj4(版本4.8.0)似乎都能顺利编译和安装;不过,使用最新的GEOS svn_trunk(版本3.3.5)时可能会遇到一些问题。请注意以下链接以获取解决方法...
如果你从577下载两个makefile,它们包含了574中的修复。
你还需要下载一个夜间快照,并将geos/src/triangulate目录复制到你的构建文件夹,因为在svn_trunk中缺少这个目录。
最后,你需要对geos/src/dirlist.mk做一个小修改:
在第45行,添加'triangulate \'(不带引号),放在'simplify \'下面,'util'上面。
现在当你编译时,可能会看到一些警告,但构建应该不会完全失败...
nmake /f makefile.vc PREFIX=../Path/To/Geos/Install/Here
nmake install /f makefile.vc PREFIX=../Path/To/Geos/Install/Here
这样就解决了你的库依赖问题。接下来你需要做两件事中的一件: 1. 在你的pyspatialite构建文件夹中创建一个setup.cfg文件,并添加/bin、/lib和/include路径,或者 2. 直接编辑pyspatialite的setup.py文件,做同样的事情。
我发现直接编辑setup.py文件最简单,添加依赖库的路径,类似于:
(line 45) include_dirs = ['../usr/local/include', '../python27/include']
(line 46) library_dirs = ['../usr/local/lib', '../python27/libs', '../usr/local/bin', '../python27/DLLs']
(line 47) libraries = ['geos','geos_c','proj','iconv'] # You may need to add 'iconv' here
(line 48) runtime_library_dirs = ['../usr/local/lib', '../python27/libs', '../usr/local/bin', '../python27/DLLs']
如果在做了这些修改后,pyspatialite仍然无法构建,那么再对setup.py做一组修改:在第121行附近,添加以下几行...
ext.include_dirs.append('../python27/include')
ext.include_dirs.append('../usr/local/include')
ext.library_dirs.append('../python27/libs')
ext.library_dirs.append('../usr/local/lib')
ext.library_dirs.append('../python27/DLLs')
ext.library_dirs.append('../usr/local/bin')
记得替换路径以匹配你的具体设置。这样就可以了。运行'python setup.py install'后,一切应该都能正常工作。
你可以在../Python27/Lib/site-packages/pyspatialite/test中运行所有测试 - 我测试的都通过了;不过,更好、更真实的测试可能是运行这个链接中的示例代码:
不过,作者提到的步骤没有详细说明如何在x64环境中让依赖库工作,我觉得这些信息并不是特别有用,因为pyspatialite 3.0.1现在会自动检测适合的spatialite合并版本进行下载。网站上的示例代码会创建一个spatialite数据库文件,并填充数千条记录。对我来说,一切都运行得很顺利;所以我相信上面提到的方法可以成功构建pyspatialite的x64版本。
祝你好运!
-RMWChaos
我之前也遇到过同样的问题,搞了好几天都没弄明白。我是在Windows 7(64位)上运行Python 2.6(32位),所以可能和你的环境不太一样。
你可以试试以下方法(来自这个Google Groups的帖子):
- 把一些叫做spatialite的dll文件(libgeos_c-1.dll、libgeos-3-0-0.dll、libproj-0.dll和libspatialite-2.dll)放到C:/盘的一个文件夹里。
- 把这个文件夹添加到你的PATH环境变量中。
问题似乎是Windows可能因为用户权限设置的原因,无法从C:\Windows\system32加载这些dll文件。
Python自带的sqlite3.dll
似乎和Spatialite不太兼容。除了从源代码编译一切之外,我找到的唯一可行的方法是:
- 下载SQLite(或者cyqlite,这是一个为Windows重新编译的SQLite,带有一些实用功能,比如R-Tree,可以用来做空间索引),也就是下载
sqlite-dll-win32-x86-[版本].zip
- 下载mod_spatialite(Windows版本的文件在页面底部的粉色框里),也就是下载
mod_spatialite-[版本]-win-x86.7z
- 先解压SQLite/cyqlite,再解压mod_spatialite到同一个文件夹(如果有文件冲突,选择覆盖)
- 把这个文件夹添加到你的系统路径中
- 把你Python的DLL目录下的
sqlite3.dll
重命名为类似sqlite3_old.dll
,这样Python就会使用你路径中的新文件
想了解更多信息,可以查看这篇博客。