Fixed #25645 -- Dropped support for SpatiaLite < 4.0.

This commit is contained in:
Tim Graham 2016-05-31 11:31:51 -04:00
parent 62e4f8ec43
commit 47f22e8286
9 changed files with 22 additions and 45 deletions

View File

@ -29,10 +29,9 @@ class SpatiaLiteIntrospection(DatabaseIntrospection):
cursor = self.connection.cursor() cursor = self.connection.cursor()
try: try:
# Querying the `geometry_columns` table to get additional metadata. # Querying the `geometry_columns` table to get additional metadata.
type_col = 'type' if self.connection.ops.spatial_version < (4, 0, 0) else 'geometry_type' cursor.execute('SELECT coord_dimension, srid, geometry_type '
cursor.execute('SELECT coord_dimension, srid, %s '
'FROM geometry_columns ' 'FROM geometry_columns '
'WHERE f_table_name=%%s AND f_geometry_column=%%s' % type_col, 'WHERE f_table_name=%s AND f_geometry_column=%s',
(table_name, geo_col)) (table_name, geo_col))
row = cursor.fetchone() row = cursor.fetchone()
if not row: if not row:

View File

@ -2,9 +2,7 @@
The GeometryColumns and SpatialRefSys models for the SpatiaLite backend. The GeometryColumns and SpatialRefSys models for the SpatiaLite backend.
""" """
from django.contrib.gis.db.backends.base.models import SpatialRefSysMixin from django.contrib.gis.db.backends.base.models import SpatialRefSysMixin
from django.contrib.gis.db.backends.spatialite.base import DatabaseWrapper from django.db import models
from django.db import connection, models
from django.db.backends.signals import connection_created
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
@ -18,6 +16,7 @@ class SpatialiteGeometryColumns(models.Model):
coord_dimension = models.IntegerField() coord_dimension = models.IntegerField()
srid = models.IntegerField(primary_key=True) srid = models.IntegerField(primary_key=True)
spatial_index_enabled = models.IntegerField() spatial_index_enabled = models.IntegerField()
type = models.IntegerField(db_column='geometry_type')
class Meta: class Meta:
app_label = 'gis' app_label = 'gis'
@ -55,6 +54,7 @@ class SpatialiteSpatialRefSys(models.Model, SpatialRefSysMixin):
auth_srid = models.IntegerField() auth_srid = models.IntegerField()
ref_sys_name = models.CharField(max_length=256) ref_sys_name = models.CharField(max_length=256)
proj4text = models.CharField(max_length=2048) proj4text = models.CharField(max_length=2048)
srtext = models.CharField(max_length=2048)
@property @property
def wkt(self): def wkt(self):
@ -67,18 +67,3 @@ class SpatialiteSpatialRefSys(models.Model, SpatialRefSysMixin):
app_label = 'gis' app_label = 'gis'
db_table = 'spatial_ref_sys' db_table = 'spatial_ref_sys'
managed = False managed = False
def add_spatial_version_related_fields(sender, **kwargs):
"""
Adds fields after establishing a database connection to prevent database
operations at compile time.
"""
if connection_created.disconnect(add_spatial_version_related_fields, sender=DatabaseWrapper):
spatial_version = connection.ops.spatial_version[0]
if spatial_version >= 4:
SpatialiteSpatialRefSys.add_to_class('srtext', models.CharField(max_length=2048))
SpatialiteGeometryColumns.add_to_class('type', models.IntegerField(db_column='geometry_type'))
else:
SpatialiteGeometryColumns.add_to_class('type', models.CharField(max_length=30))
connection_created.connect(add_spatial_version_related_fields, sender=DatabaseWrapper)

View File

@ -1,6 +1,5 @@
""" """
SQL functions reference lists: SQL functions reference lists:
http://www.gaia-gis.it/spatialite-3.0.0-BETA/spatialite-sql-3.0.0.html
https://web.archive.org/web/20130407175746/http://www.gaia-gis.it/gaia-sins/spatialite-sql-4.0.0.html https://web.archive.org/web/20130407175746/http://www.gaia-gis.it/gaia-sins/spatialite-sql-4.0.0.html
http://www.gaia-gis.it/gaia-sins/spatialite-sql-4.2.1.html http://www.gaia-gis.it/gaia-sins/spatialite-sql-4.2.1.html
""" """
@ -90,18 +89,14 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
'Length': 'ST_Length', 'Length': 'ST_Length',
'Reverse': 'ST_Reverse', 'Reverse': 'ST_Reverse',
'Scale': 'ScaleCoords', 'Scale': 'ScaleCoords',
'Translate': 'ST_Translate' if self.spatial_version >= (3, 1, 0) else 'ShiftCoords', 'Translate': 'ST_Translate',
'Union': 'ST_Union', 'Union': 'ST_Union',
} }
@cached_property @cached_property
def unsupported_functions(self): def unsupported_functions(self):
unsupported = {'BoundingCircle', 'ForceRHR', 'IsValid', 'MakeValid', 'MemSize'} unsupported = {'BoundingCircle', 'ForceRHR', 'IsValid', 'MakeValid', 'MemSize'}
if self.spatial_version < (3, 1, 0): if not self.lwgeom_version():
unsupported.add('SnapToGrid')
if self.spatial_version < (4, 0, 0):
unsupported.update({'Perimeter', 'Reverse'})
elif not self.lwgeom_version():
unsupported.add('GeoHash') unsupported.add('GeoHash')
return unsupported return unsupported
@ -116,8 +111,8 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
'database (error was "%s"). Was the SpatiaLite initialization ' 'database (error was "%s"). Was the SpatiaLite initialization '
'SQL loaded on this database?') % (self.connection.settings_dict['NAME'], msg) 'SQL loaded on this database?') % (self.connection.settings_dict['NAME'], msg)
six.reraise(ImproperlyConfigured, ImproperlyConfigured(new_msg), sys.exc_info()[2]) six.reraise(ImproperlyConfigured, ImproperlyConfigured(new_msg), sys.exc_info()[2])
if version < (3, 0, 0): if version < (4, 0, 0):
raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions 3.0.0 and above.') raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions 4.0.0 and above.')
return version return version
def convert_extent(self, box, srid): def convert_extent(self, box, srid):

View File

@ -388,7 +388,7 @@ Function PostGIS Oracle MySQL SpatiaLite
:class:`Distance` X X X (≥ 5.6.1) X :class:`Distance` X X X (≥ 5.6.1) X
:class:`Envelope` X X X :class:`Envelope` X X X
:class:`ForceRHR` X :class:`ForceRHR` X
:class:`GeoHash` X X (≥ 4.0, LWGEOM) :class:`GeoHash` X X (LWGEOM)
:class:`Intersection` X X X (≥ 5.6.1) X :class:`Intersection` X X X (≥ 5.6.1) X
:class:`IsValid` X :class:`IsValid` X
:class:`Length` X X X X :class:`Length` X X X X
@ -396,11 +396,11 @@ Function PostGIS Oracle MySQL SpatiaLite
:class:`MemSize` X :class:`MemSize` X
:class:`NumGeometries` X X X X :class:`NumGeometries` X X X X
:class:`NumPoints` X X X X :class:`NumPoints` X X X X
:class:`Perimeter` X X X (≥ 4.0) :class:`Perimeter` X X X
:class:`PointOnSurface` X X X :class:`PointOnSurface` X X X
:class:`Reverse` X X X (≥ 4.0) :class:`Reverse` X X X
:class:`Scale` X X :class:`Scale` X X
:class:`SnapToGrid` X X (≥ 3.1) :class:`SnapToGrid` X X
:class:`SymDifference` X X X (≥ 5.6.1) X :class:`SymDifference` X X X (≥ 5.6.1) X
:class:`Transform` X X X :class:`Transform` X X X
:class:`Translate` X X :class:`Translate` X X

View File

@ -263,7 +263,7 @@ right-hand rule.
.. class:: GeoHash(expression, **extra) .. class:: GeoHash(expression, **extra)
*Availability*: PostGIS, SpatiaLite (≥ 4.0, LWGEOM) *Availability*: PostGIS, SpatiaLite (LWGEOM)
Accepts a single geographic field or expression and returns a `GeoHash`__ Accepts a single geographic field or expression and returns a `GeoHash`__
representation of the geometry. representation of the geometry.
@ -367,7 +367,7 @@ in the first linestring in the geometry field; otherwise returns ``None``.
.. class:: Perimeter(expression, **extra) .. class:: Perimeter(expression, **extra)
*Availability*: PostGIS, Oracle, SpatiaLite (≥ 4.0) *Availability*: PostGIS, Oracle, SpatiaLite
Accepts a single geographic field or expression and returns the perimeter of the Accepts a single geographic field or expression and returns the perimeter of the
geometry field as a :class:`~django.contrib.gis.measure.Distance` object. On geometry field as a :class:`~django.contrib.gis.measure.Distance` object. On
@ -389,7 +389,7 @@ guaranteed to lie on the surface of the field; otherwise returns ``None``.
.. class:: Reverse(expression, **extra) .. class:: Reverse(expression, **extra)
*Availability*: PostGIS, Oracle, SpatiaLite (≥ 4.0) *Availability*: PostGIS, Oracle, SpatiaLite
Accepts a single geographic field or expression and returns a geometry with Accepts a single geographic field or expression and returns a geometry with
reversed coordinates. reversed coordinates.
@ -410,7 +410,7 @@ scaled coordinates by multiplying them with the ``x``, ``y``, and optionally
.. class:: SnapToGrid(expression, *args, **extra) .. class:: SnapToGrid(expression, *args, **extra)
*Availability*: PostGIS, SpatiaLite (≥ 3.1) *Availability*: PostGIS, SpatiaLite
Accepts a single geographic field or expression and returns a geometry with all Accepts a single geographic field or expression and returns a geometry with all
points snapped to the given grid. How the geometry is snapped to the grid points snapped to the given grid. How the geometry is snapped to the grid

View File

@ -13,7 +13,7 @@ Program Description Required
:doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes (SQLite only) 2.1, 2.0, 1.11, 1.10, 1.9, 1.8, 1.7 :doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes (SQLite only) 2.1, 2.0, 1.11, 1.10, 1.9, 1.8, 1.7
:doc:`GeoIP <../geoip>` IP-based geolocation library No 1.4 :doc:`GeoIP <../geoip>` IP-based geolocation library No 1.4
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 2.2, 2.1, 2.0 `PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 2.2, 2.1, 2.0
`SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.3, 4.2, 4.1, 4.0, 3.0 `SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.3, 4.2, 4.1, 4.0
======================== ==================================== ================================ =================================== ======================== ==================================== ================================ ===================================
Note that older or more recent versions of these libraries *may* also work Note that older or more recent versions of these libraries *may* also work
@ -33,7 +33,6 @@ totally fine with GeoDjango. Your mileage may vary.
PostGIS 2.0.0 2012-04-03 PostGIS 2.0.0 2012-04-03
PostGIS 2.1.0 2013-08-17 PostGIS 2.1.0 2013-08-17
PostGIS 2.2.0 2015-10-17 PostGIS 2.2.0 2015-10-17
Spatialite 3.0.0 2011-12-30
Spatialite 4.0.0 2012-11-25 Spatialite 4.0.0 2012-11-25
Spatialite 4.1.0 2013-06-04 Spatialite 4.1.0 2013-06-04
Spatialite 4.2.0 2014-07-25 Spatialite 4.2.0 2014-07-25

View File

@ -61,7 +61,7 @@ Database Library Requirements Supported Versions Notes
PostgreSQL GEOS, PROJ.4, PostGIS 9.2+ Requires PostGIS. PostgreSQL GEOS, PROJ.4, PostGIS 9.2+ Requires PostGIS.
MySQL GEOS 5.5+ Not OGC-compliant; :ref:`limited functionality <mysql-spatial-limitations>`. MySQL GEOS 5.5+ Not OGC-compliant; :ref:`limited functionality <mysql-spatial-limitations>`.
Oracle GEOS 11.2+ XE not supported. Oracle GEOS 11.2+ XE not supported.
SQLite GEOS, GDAL, PROJ.4, SpatiaLite 3.6.+ Requires SpatiaLite 3.0+, pysqlite2 2.5+ SQLite GEOS, GDAL, PROJ.4, SpatiaLite 3.6.+ Requires SpatiaLite 4.0+, pysqlite2 2.5+
================== ============================== ================== ========================================= ================== ============================== ================== =========================================
See also `this comparison matrix`__ on the OSGeo Wiki for See also `this comparison matrix`__ on the OSGeo Wiki for

View File

@ -213,6 +213,8 @@ Miscellaneous
the current UTC date/time, instead of a datetime without any timezone the current UTC date/time, instead of a datetime without any timezone
information. information.
* Support for SpatiaLite < 4.0 is dropped.
.. _deprecated-features-1.11: .. _deprecated-features-1.11:
Features deprecated in 1.11 Features deprecated in 1.11

View File

@ -2,7 +2,6 @@ import re
import unittest import unittest
from django.contrib.gis.gdal import HAS_GDAL from django.contrib.gis.gdal import HAS_GDAL
from django.db import connection
from django.test import mock, skipUnlessDBFeature from django.test import mock, skipUnlessDBFeature
from django.utils import six from django.utils import six
@ -110,8 +109,6 @@ class SpatialRefSysTest(unittest.TestCase):
if postgis or spatialite: if postgis or spatialite:
srs = sr.srs srs = sr.srs
six.assertRegex(self, srs.proj4, sd['proj4_re']) six.assertRegex(self, srs.proj4, sd['proj4_re'])
# No `srtext` field in the `spatial_ref_sys` table in SpatiaLite < 4
if not spatialite or connection.ops.spatial_version[0] >= 4:
self.assertTrue(srs.wkt.startswith(sd['srtext'])) self.assertTrue(srs.wkt.startswith(sd['srtext']))
def test_ellipsoid(self): def test_ellipsoid(self):