Python中Sqlite加载spatialite扩展失败

12 投票
4 回答
11955 浏览
提问于 2025-04-17 08:46

我正在尝试使用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 个回答

1

我最近经历了一场关于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)时可能会遇到一些问题。请注意以下链接以获取解决方法...

OSGEO GEOS TRAC 票据 #574

OSGEO GEOS TRAC 票据 #577

如果你从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中运行所有测试 - 我测试的都通过了;不过,更好、更真实的测试可能是运行这个链接中的示例代码:

SpatiaLite和Python

不过,作者提到的步骤没有详细说明如何在x64环境中让依赖库工作,我觉得这些信息并不是特别有用,因为pyspatialite 3.0.1现在会自动检测适合的spatialite合并版本进行下载。网站上的示例代码会创建一个spatialite数据库文件,并填充数千条记录。对我来说,一切都运行得很顺利;所以我相信上面提到的方法可以成功构建pyspatialite的x64版本。

祝你好运!

-RMWChaos

2

我之前也遇到过同样的问题,搞了好几天都没弄明白。我是在Windows 7(64位)上运行Python 2.6(32位),所以可能和你的环境不太一样。

你可以试试以下方法(来自这个Google Groups的帖子):

  1. 把一些叫做spatialite的dll文件(libgeos_c-1.dll、libgeos-3-0-0.dll、libproj-0.dll和libspatialite-2.dll)放到C:/盘的一个文件夹里。
  2. 把这个文件夹添加到你的PATH环境变量中。

问题似乎是Windows可能因为用户权限设置的原因,无法从C:\Windows\system32加载这些dll文件。

3

Python自带的sqlite3.dll似乎和Spatialite不太兼容。除了从源代码编译一切之外,我找到的唯一可行的方法是:

  1. 下载SQLite(或者cyqlite,这是一个为Windows重新编译的SQLite,带有一些实用功能,比如R-Tree,可以用来做空间索引),也就是下载sqlite-dll-win32-x86-[版本].zip
  2. 下载mod_spatialite(Windows版本的文件在页面底部的粉色框里),也就是下载mod_spatialite-[版本]-win-x86.7z
  3. 先解压SQLite/cyqlite,再解压mod_spatialite同一个文件夹(如果有文件冲突,选择覆盖)
  4. 把这个文件夹添加到你的系统路径中
  5. 把你Python的DLL目录下的sqlite3.dll重命名为类似sqlite3_old.dll,这样Python就会使用你路径中的新文件

想了解更多信息,可以查看这篇博客

撰写回答