I installed spatialite
for Django
project but when I try to migrate it show me this error :
File \"/Library/Frameworks/Python.frame
The ImproperlyConfigured
error is raised in django.contrib.gis.db.backends.spatialite.base
when using a Python build based on the default sqlite3 library - which is the case for MacOSX and probably most Linux distros - which was built with extension loading disabled. So, this won't work:
conn.enable_load_extension(True)
conn.load_extension(SPATIALITE_LIBRARY_PATH)
Following the directions of the GeoDjango won't solve the problem in most cases. Even installing the spatialite-tools
via Homebrew only installs new spatialite and sqlite executables and libraries in the Homebrew directory.
Assuming sqlite and spatialite are installed (e.g. via Homebrew) and the respective sqlite version has load_extention
enabled, you can build Python from scratch with this sqlite library linked. It's pretty easy using pyenv. Specific build options can be provided via the PYTHON_CONFIGURE_OPTS
environment variable (details here) and setting CPPFLAGS
and LDFLAGS
(see here)
Building with pyenv assuming sqlite was installed via homebrew (check which sqlite3
and brew info sqlite
for details on which versions are installed and where):
PYTHON_CONFIGURE_OPTS="--enable-loadable-sqlite-extensions --enable-optimizations --with-openssl=\$(brew --prefix openssl)" \
LDFLAGS="-L/usr/local/opt/sqlite/lib" \
CPPFLAGS="-I/usr/local/opt/sqlite/include" \
pyenv install 3.8.2
If dependencies are missing (e.g. openssl), see below on building Python manually.
Finally, it's important to reference the dynamically linked spatialite in your Django settings (so make sure /usr/local/lib/mod_spatialite.dylib
exists)
SPATIALITE_LIBRARY_PATH = '/usr/local/lib/mod_spatialite.dylib'
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.spatialite',
'NAME': os.path.join(BASE_DIR, 'db.spatialite3'),
}
}
To compile sqlite from source with load extensions enabled (see docs), download the amalgamated source file from the website and follow the instructions. You'll want to include the build option -DSQLITE_ENABLE_RTREE
but NOT -DSQLITE_OMIT_LOAD_EXTENSION
!
Once sqlite3 compiled, run the executable and check via the command .dbconfig
sqlite > .dbconfig
[...]
load_extension on
[...]
Loading extensions is turned off by default, to avoid security issues.
Building Python manually is also pretty straightforward and follows a similar pattern as installing via pyenv. Once dependencies are met (e.g. on macos brew install openssl xz gdbm
), you download the tarball with the desired version and set the compile options to enable sqlite extension loading (and telling make where to find your newly compiled SQLite build):
./configure --enable-loadable-sqlite-extensions --enable-optimizations --with-openssl=$(brew --prefix openssl)
LDFLAGS="-L<path-to-sqlite>" \
CPPFLAGS="-I<path-to-sqlite>" \
make -j2
The described solution applied to MacOS primarily and Python3, since sqlite3 ships as part of the standard python library for Python3, as opposed to a seprate package for Python 2. Previous solutions, such as [pysqlite] only work for Python2 which is EOL.
What you tried may have been based on an older solution, which may have applied to Python2.
Also, there seemed to have been proposed other solutions for Windows using cyqlite