Open tacree-odot opened 5 years ago
I have this same problem - is there any progress?
Same problem here. I've tried both the anaconda and the conda-forge channels for libspatialite and get the exact same result. Here's the result from conda create -n test libspatialite python
using python 3.8.5.
Test code:
from ctypes import util
lib = util.find_library('spatialite')
print('spatialite library: ', lib)
import sys
for p in sys.path:
print(p)
import sqlite3
connection = sqlite3.connect('geotest')
connection.enable_load_extension(True)
connection.load_extension('spatialite.dll')
And the results:
spatialite library: C:\Users\witr\miniconda3\envs\test\Library\bin\spatialite.dll
C:\Users\witr\Documents\Python Scripts\geo
C:\Users\witr\miniconda3\envs\test\python38.zip
C:\Users\witr\miniconda3\envs\test\DLLs
C:\Users\witr\miniconda3\envs\test\lib
C:\Users\witr\miniconda3\envs\test
C:\Users\witr\miniconda3\envs\test\lib\site-packages
Traceback (most recent call last):
File "geo.py", line 16, in <module>
connection.load_extension('spatialite.dll')
sqlite3.OperationalError: The specified procedure could not be found.
This looks like the sqlite is possibly build without extension loading. Does it work with other extensions?
@bradh , As far as I can tell, extension loading is enabled in current conda builds and it certainly seems to be trying to load the spatialite extension. I found anaconda bug reports indicating that it wasn't enabled in the past and that was fixed. I don't know of a simple extension to load (I've looked some, but this is sort of out of my area of knowledge) but if you can suggest one, I'll try it.
For others: this is being discussed in more detail on the spatialite google group.
I found anaconda bug reports indicating that it wasn't enabled in the past and that was fixed. I don't know of a simple extension to load (I've looked some, but this is sort of out of my area of knowledge) but if you can suggest one, I'll try it.
Good to know, I've been replacing their sqlite3.dll
for a while. I did test with the conda DLL now and indeed it's capable of loading extensions. :)
Trying to reproduce @BigBaaadBob's comment with conda create -n test libspatialite python
, indeed it doesn't work. The (see edit)spatialite.dll
installed doesn't contain sqlite3_modspatialite_init
. That's probably the issue -- this is probably not the extension module version of Spatialite.
If I use my own build of Spatialite (more precisely of mod_spatialite.dll
), it works as expected.
EDIT: Interesting... The old official build doesn't work either.
My build uses MSVC, I imagine there could be DLL version conflicts with the old builds.
After playing with this, I think there are multiple issues are play.
If your shared library ends up being named "YourCode.so" or "YourCode.dll" or "YourCode.dylib" as shown in the compiler examples above, then the correct entry point name would be "sqlite3_yourcode_init".
So sqlite3_spatialite_init
or sqlite3_modspatialite_init
is indeed missing, would explain why it doesn't load on Windows. On Linux, the extension can be loaded from mod_spatialite.so
(containing sqlite3_modspatialite_init
), which is installed by the conda package along with libspatialite.so
.
Depending on the Python version, the R-tree extension is not built in the Anaconda sqlite3.dll
. It seems that at least Python 3.6 has this issue. I think the official CPython releases also don't include that.
Old sqlite3.dll
from Anaconda (and I believe also from the official CPython distributions) wasn't built with extension support, so that's the original reason why nothing worked before.
There could be issues with old DLLs and Anaconda. IIRC, conda uses some custom code to set search paths, but I'm not sure what's the current situation.
Thanks @PMeira for digging in to this. Comments/questions:
I'm totally new at conda and spatialite so I'm learning as I go along...
- I'd like to drive this to some closure so I want to put a bug report somewhere. I don't quite know where to do that. Conda-forge or the feedstocks thingy? Thoughts?
@BigBaaadBob Conda-forge is a separate thing, it's a community project, this issue ticket is about the official Anaconda distribution. About the separate conda-forge version, it's also broken on Windows, its feedstock is https://github.com/conda-forge/libspatialite-feedstock and I found a ticket on the same issue already: https://github.com/conda-forge/libspatialite-feedstock/issues/49 -- maybe we should try to help there since we haven't got any replies from the official Anaconda team.
I think this issue is the right place to report the problem about the official package, as the README states:
Please submit Anaconda issues to the issue tracker of this repository.
Note: This issue tracker is for issues with the Anaconda Python distribution, its installers, and its packages. For issues with the Conda package manager unrelated to any specific package, please use the Conda issue tracker.
This is an issue with an official Anaconda package on Windows (Linux is fine, didn't test on macOS). I'm not aware of public feedstock repos for the official packages, but I could be just ignorant in this case. EDIT: Found the feedstock for the official package: https://github.com/AnacondaRecipes/libspatialite-feedstock -- it's forked from the conda-forge, probably easier to work on fixing the conda-forge version.
Of course, since I'm not a paying Anaconda customer, I wouldn't blame them for giving this low priority. There are 1.7k open issues in repo, probably not a great signal-to-noise ratio. It's a shame the package has been broken for so long though.
- From reading the spatialite documentation, the mod_spatialite DLL is the only one that will work for dynamic loading and it isn't in the libspatialite conda package. That should be part of the bug report.
Yep. I'll include some more details below about the package.
Usually the conda-build recipe is included in the final package. The current test included is just this (the conda-forge version is very similar):
import os
import sys
import ctypes
import platform
if sys.platform == 'win32':
libfreexl = ctypes.CDLL('spatialite.dll')
elif sys.platform == 'darwin':
# LD_LIBRARY_PATH not set on OS X or Linux.
path = os.path.expandvars('$PREFIX/lib/libspatialite.dylib')
libfreexl = ctypes.CDLL(path)
elif sys.platform.startswith('linux'):
path = os.path.expandvars('$PREFIX/lib/libspatialite.so')
libfreexl = ctypes.CDLL(path)
else:
raise Exception('Cannot recognize platform {!r}'.format(sys.platform))
I suggest adding a test for actually loading the extension:
import sqlite3
db = sqlite3.connect(':memory:')
db.enable_load_extension(True)
db.execute("select load_extension('mod_spatialite')")
Looking further for why the mod_spatialite.dll
is missing, it looks like the package just runs the makefile.vc
from the official with a tiny patch. That Makefile doesn't build mod_spatialite
, so there we go, that's the root cause.
(Sidenote: For my version I use custom CMake scripts, nowadays coupled with Conan. Maybe I should update and upload them somewhere for Spatialite 5.0. Right now I remove the parts that depend on GPLed libraries.)
As a reminder, this might be a good time to fix it since the new Spatialite 5.0 is in the RC phase. The build scripts for 5.0 seem to work better with MSVC. There are also new, different dependencies from Spatialite 4.3.0a.
- Is there some way of using the existing libspatialite DLL without dynamically loading it that might have been intended? Maybe combining the sqlite3.dll and the libspatialite.dll somehow?
I don't think so, the mod_spatialite
version has extra symbols. Maybe older Spatialite versions were not extensions, maybe those ones could be used in place of the SQLite3 DLL. Not worth the trouble nowadays, better to fix the package.
4. Finally, I've also found some 32/64 bit issues with the spatialite libraries that I've reported on the google group mentioned above. That might be what Paulo means above regarding MSVC.
The Spatialite 5.0 RC1 binaries seem to work it we put them in a folder listed in the PATH environment variable. You could also put them in the conda environment (subfolder Library/bin
) to emulate what a correct package should do. Long term, it's better to fix the package since Spatialite depend on a lot of DLLs, and it's quite likely that some of the DLLs will have conflicts with the ones from the conda installation.
For other versions, there might also be a conflict of the runtime libraries of MSVC and/or GCC, or missing symbols in the sqlite3.dll
like I mentioned in my other post, etc.
What I meant by this:
conda uses some custom code to set search paths, but I'm not sure what's the current situation.
...is that, by default, Windows will allow loading the DLLs as long as they are in the folder. For example, if I downloaded Spatialite 5.0 RC1 and extract that in c:\spatialite
, running db.execute(r"select load_extension('c:\spatialite\mod_spatialite.dll')"
used to work. I'm not sure if the change was in Anaconda itself or Python 3.8 in general, but now the DLLs need to be in the path (it seems either one of those DLL folders inside the conda environment or the general executable path). Even though the required DLLs are side-by-side in c:\spatialite
, they won't be loaded if they're not in the allowed paths, leading to The specified module could not be found.
I'm totally new at conda and spatialite so I'm learning as I go along...
Please let me know if I could clarify anything.
Actual Behavior
When attempting to load the spatialite extension, I am receiving the error:
sqlite3.OperationalError: The specified module could not be found.
I have tried loading this extension multiple ways, and none of them seem to work. See errors below in the output.
Expected Behavior
The extension should load. Note that I have verified that the spatialite dll is in the environment, I am printing it in the script below.
Steps to Reproduce
I have produced the following script to demonstrate the issue below:
Script output:
Anaconda or Miniconda version:
Anaconda3-2019.03-Windows-x86_64
Operating System:
Windows 10
conda info
conda list --show-channel-urls