Skip to content

Commit

Permalink
Fixed #24499 -- Dropped support for PostGIS 1.5.
Browse files Browse the repository at this point in the history
  • Loading branch information
timgraham committed Apr 25, 2015
1 parent faad607 commit 26996e2
Show file tree
Hide file tree
Showing 13 changed files with 26 additions and 273 deletions.
20 changes: 3 additions & 17 deletions django/contrib/gis/db/backends/postgis/base.py
@@ -1,10 +1,7 @@
from django.conf import settings
from django.db.backends.base.base import NO_DB_ALIAS
from django.db.backends.postgresql_psycopg2.base import \
DatabaseWrapper as Psycopg2DatabaseWrapper
from django.utils.functional import cached_property

from .creation import PostGISCreation
from .features import DatabaseFeatures
from .introspection import PostGISIntrospection
from .operations import PostGISOperations
Expand All @@ -18,22 +15,11 @@ def __init__(self, *args, **kwargs):
super(DatabaseWrapper, self).__init__(*args, **kwargs)
if kwargs.get('alias', '') != NO_DB_ALIAS:
self.features = DatabaseFeatures(self)
self.creation = PostGISCreation(self)
self.ops = PostGISOperations(self)
self.introspection = PostGISIntrospection(self)

@cached_property
def template_postgis(self):
template_postgis = getattr(settings, 'POSTGIS_TEMPLATE', 'template_postgis')
with self._nodb_connection.cursor() as cursor:
cursor.execute('SELECT 1 FROM pg_database WHERE datname = %s LIMIT 1;', (template_postgis,))
if cursor.fetchone():
return template_postgis
return None

def prepare_database(self):
super(DatabaseWrapper, self).prepare_database()
if self.template_postgis is None:
# Check that postgis extension is installed on PostGIS >= 2
with self.cursor() as cursor:
cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis")
# Check that postgis extension is installed.
with self.cursor() as cursor:
cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis")
10 changes: 0 additions & 10 deletions django/contrib/gis/db/backends/postgis/creation.py

This file was deleted.

41 changes: 7 additions & 34 deletions django/contrib/gis/db/backends/postgis/operations.py
Expand Up @@ -110,19 +110,22 @@ def __init__(self, connection):
self.distance_spheroid = prefix + 'distance_spheroid'
self.envelope = prefix + 'Envelope'
self.extent = prefix + 'Extent'
self.extent3d = prefix + '3DExtent'
self.force_rhr = prefix + 'ForceRHR'
self.geohash = prefix + 'GeoHash'
self.geojson = prefix + 'AsGeoJson'
self.gml = prefix + 'AsGML'
self.intersection = prefix + 'Intersection'
self.kml = prefix + 'AsKML'
self.length = prefix + 'Length'
self.length3d = prefix + '3DLength'
self.length_spheroid = prefix + 'length_spheroid'
self.makeline = prefix + 'MakeLine'
self.mem_size = prefix + 'mem_size'
self.num_geom = prefix + 'NumGeometries'
self.num_points = prefix + 'npoints'
self.perimeter = prefix + 'Perimeter'
self.perimeter3d = prefix + '3DPerimeter'
self.point_on_surface = prefix + 'PointOnSurface'
self.polygonize = prefix + 'Polygonize'
self.reverse = prefix + 'Reverse'
Expand All @@ -135,34 +138,6 @@ def __init__(self, connection):
self.union = prefix + 'Union'
self.unionagg = prefix + 'Union'

# Following "attributes" are properties due to the spatial_version check and
# to delay database access
@property
def extent3d(self):
if self.spatial_version >= (2, 0, 0):
return self.geom_func_prefix + '3DExtent'
else:
return self.geom_func_prefix + 'Extent3D'

@property
def length3d(self):
if self.spatial_version >= (2, 0, 0):
return self.geom_func_prefix + '3DLength'
else:
return self.geom_func_prefix + 'Length3D'

@property
def perimeter3d(self):
if self.spatial_version >= (2, 0, 0):
return self.geom_func_prefix + '3DPerimeter'
else:
return self.geom_func_prefix + 'Perimeter3D'

@property
def geometry(self):
# Native geometry type support added in PostGIS 2.0.
return self.spatial_version >= (2, 0, 0)

@cached_property
def spatial_version(self):
"""Determine the version of the PostGIS library."""
Expand All @@ -180,7 +155,7 @@ def spatial_version(self):
except ProgrammingError:
raise ImproperlyConfigured(
'Cannot determine PostGIS version for database "%s". '
'GeoDjango requires at least PostGIS version 1.5. '
'GeoDjango requires at least PostGIS version 2.0. '
'Was the database created from a spatial database '
'template?' % self.connection.settings_dict['NAME']
)
Expand Down Expand Up @@ -234,16 +209,14 @@ def geo_db_type(self, f):
raise NotImplementedError('PostGIS only supports geography columns with an SRID of 4326.')

return 'geography(%s,%d)' % (f.geom_type, f.srid)
elif self.geometry:
# Postgis 2.0 supports type-based geometries.
else:
# Type-based geometries.
# TODO: Support 'M' extension.
if f.dim == 3:
geom_type = f.geom_type + 'Z'
else:
geom_type = f.geom_type
return 'geometry(%s,%d)' % (geom_type, f.srid)
else:
return None

def get_distance(self, f, dist_val, lookup_type):
"""
Expand All @@ -253,7 +226,7 @@ def get_distance(self, f, dist_val, lookup_type):
This is the most complex implementation of the spatial backends due to
what is supported on geodetic geometry columns vs. what's available on
projected geometry columns. In addition, it has to take into account
the geography column type newly introduced in PostGIS 1.5.
the geography column type.
"""
# Getting the distance parameter and any options.
if len(dist_val) == 1:
Expand Down
55 changes: 5 additions & 50 deletions django/contrib/gis/db/backends/postgis/schema.py
Expand Up @@ -3,12 +3,8 @@

class PostGISSchemaEditor(DatabaseSchemaEditor):
geom_index_type = 'GIST'
geom_index_ops = 'GIST_GEOMETRY_OPS'
geom_index_ops_nd = 'GIST_GEOMETRY_OPS_ND'

sql_add_geometry_column = "SELECT AddGeometryColumn(%(table)s, %(column)s, %(srid)s, %(geom_type)s, %(dim)s)"
sql_drop_geometry_column = "SELECT DropGeometryColumn(%(table)s, %(column)s)"
sql_alter_geometry_column_not_null = "ALTER TABLE %(table)s ALTER COLUMN %(column)s SET NOT NULL"
sql_add_spatial_index = "CREATE INDEX %(index)s ON %(table)s USING %(index_type)s (%(column)s %(ops)s)"
sql_clear_geometry_columns = "DELETE FROM geometry_columns WHERE f_table_name = %(table)s"

Expand All @@ -24,48 +20,21 @@ def column_sql(self, model, field, include_default=False):
if not isinstance(field, GeometryField):
return super(PostGISSchemaEditor, self).column_sql(model, field, include_default)

if field.geography or self.connection.ops.geometry:
# Geography and Geometry (PostGIS 2.0+) columns are
# created normally.
column_sql = super(PostGISSchemaEditor, self).column_sql(model, field, include_default)
else:
column_sql = None, None
# Geometry columns are created by the `AddGeometryColumn`
# stored procedure.
self.geometry_sql.append(
self.sql_add_geometry_column % {
"table": self.geo_quote_name(model._meta.db_table),
"column": self.geo_quote_name(field.column),
"srid": field.srid,
"geom_type": self.geo_quote_name(field.geom_type),
"dim": field.dim,
}
)

if not field.null:
self.geometry_sql.append(
self.sql_alter_geometry_column_not_null % {
"table": self.quote_name(model._meta.db_table),
"column": self.quote_name(field.column),
}
)
column_sql = super(PostGISSchemaEditor, self).column_sql(model, field, include_default)

if field.spatial_index:
# Spatial indexes created the same way for both Geometry and
# Geography columns.
# PostGIS 2.0 does not support GIST_GEOMETRY_OPS. So, on 1.5
# we use GIST_GEOMETRY_OPS, on 2.0 we use either "nd" ops
# which are fast on multidimensional cases, or just plain
# gist index for the 2d case.

if field.geography:
index_ops = ''
elif self.connection.ops.geometry:
else:
# Use either "nd" ops which are fast on multidimensional cases
# or just plain gist index for the 2d case.
if field.dim > 2:
index_ops = self.geom_index_ops_nd
else:
index_ops = ''
else:
index_ops = self.geom_index_ops
self.geometry_sql.append(
self.sql_add_spatial_index % {
"index": self.quote_name('%s_%s_id' % (model._meta.db_table, field.column)),
Expand Down Expand Up @@ -96,17 +65,3 @@ def add_field(self, model, field):
for sql in self.geometry_sql:
self.execute(sql)
self.geometry_sql = []

def remove_field(self, model, field):
from django.contrib.gis.db.models.fields import GeometryField
if not isinstance(field, GeometryField) or \
self.connection.ops.spatial_version > (2, 0) or \
field.geography:
super(PostGISSchemaEditor, self).remove_field(model, field)
else:
self.execute(
self.sql_drop_geometry_column % {
"table": self.geo_quote_name(model._meta.db_table),
"column": self.geo_quote_name(field.column),
}
)
4 changes: 2 additions & 2 deletions django/db/backends/base/schema.py
Expand Up @@ -462,8 +462,8 @@ def alter_field(self, model, old_field, new_field, strict=False):
(new_type is None and new_field.remote_field is None)):
raise ValueError(
"Cannot alter field %s into %s - they do not properly define "
"db_type (are you using PostGIS 1.5 or badly-written custom "
"fields?)" % (old_field, new_field),
"db_type (are you using a badly-written custom field?)" %
(old_field, new_field),
)
elif old_type is None and new_type is None and (
old_field.remote_field.through and new_field.remote_field.through and
Expand Down
16 changes: 0 additions & 16 deletions docs/ref/contrib/gis/install/create_template_postgis-1.5.sh

This file was deleted.

18 changes: 0 additions & 18 deletions docs/ref/contrib/gis/install/create_template_postgis-debian.sh

This file was deleted.

3 changes: 1 addition & 2 deletions docs/ref/contrib/gis/install/geolibs.txt
Expand Up @@ -12,7 +12,7 @@ Program Description Required
`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 4.9, 4.8, 4.7, 4.6, 4.5, 4.4
:doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes (SQLite only) 1.11, 1.10, 1.9, 1.8, 1.7
:doc:`GeoIP <../geoip>` IP-based geolocation library No 1.4
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 2.1, 2.0, 1.5
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 2.1, 2.0
`SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.1, 4.0, 3.0, 2.4
======================== ==================================== ================================ ============================

Expand All @@ -29,7 +29,6 @@ totally fine with GeoDjango. Your mileage may vary.
GDAL 1.9.0 2012-01-03
GDAL 1.10.0 2013-04-29
GDAL 1.11.0 2014-04-25
PostGIS 1.5.0 2010-02-04
PostGIS 2.0.0 2012-04-03
PostGIS 2.1.0 2013-08-17
Spatialite 2.4.0 2010-11-14
Expand Down

0 comments on commit 26996e2

Please sign in to comment.