Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Use native geometry types on PostGIS 2.0+ instead of `AddGeometryColu…

…mn` and don't query database in `PostGISCreation.sql_table_creation_suffix`.
  • Loading branch information...
commit 91ef2a5253a50a602523bdda943c32c4cfe719fe 1 parent b6b8a3f
@jbronn jbronn authored
View
3  django/contrib/gis/db/backends/base.py
@@ -32,8 +32,9 @@ class BaseSpatialOperations(object):
# How the geometry column should be selected.
select = None
- # Does the spatial database have a geography type?
+ # Does the spatial database have a geometry or geography type?
geography = False
+ geometry = False
area = False
centroid = False
View
32 django/contrib/gis/db/backends/postgis/creation.py
@@ -4,7 +4,8 @@
class PostGISCreation(DatabaseCreation):
geom_index_type = 'GIST'
- geom_index_opts = 'GIST_GEOMETRY_OPS'
+ geom_index_ops = 'GIST_GEOMETRY_OPS'
+ geom_index_ops_nd = 'GIST_GEOMETRY_OPS_ND'
def sql_indexes_for_field(self, model, f, style):
"Return any spatial index creation SQL for the field."
@@ -17,8 +18,9 @@ def sql_indexes_for_field(self, model, f, style):
qn = self.connection.ops.quote_name
db_table = model._meta.db_table
- if f.geography:
- # Geogrophy columns are created normally.
+ if f.geography or self.connection.ops.geometry:
+ # Geography and Geometry (PostGIS 2.0+) columns are
+ # created normally.
pass
else:
# Geometry columns are created by `AddGeometryColumn`
@@ -47,33 +49,23 @@ def sql_indexes_for_field(self, model, f, style):
# which are fast on multidimensional cases, or just plain
# gist index for the 2d case.
if f.geography:
- index_opts = ''
- elif self.connection.ops.spatial_version >= (2, 0):
+ index_ops = ''
+ elif self.connection.ops.geometry:
if f.dim > 2:
- index_opts = ' ' + style.SQL_KEYWORD('gist_geometry_ops_nd')
+ index_ops = ' ' + style.SQL_KEYWORD(self.geom_index_ops_nd)
else:
- index_opts = ''
+ index_ops = ''
else:
- index_opts = ' ' + style.SQL_KEYWORD(self.geom_index_opts)
+ index_ops = ' ' + style.SQL_KEYWORD(self.geom_index_ops)
output.append(style.SQL_KEYWORD('CREATE INDEX ') +
style.SQL_TABLE(qn('%s_%s_id' % (db_table, f.column))) +
style.SQL_KEYWORD(' ON ') +
style.SQL_TABLE(qn(db_table)) +
style.SQL_KEYWORD(' USING ') +
style.SQL_COLTYPE(self.geom_index_type) + ' ( ' +
- style.SQL_FIELD(qn(f.column)) + index_opts + ' );')
+ style.SQL_FIELD(qn(f.column)) + index_ops + ' );')
return output
def sql_table_creation_suffix(self):
- cursor = self.connection.cursor()
- cursor.execute('SELECT datname FROM pg_database;')
- db_names = [row[0] for row in cursor.fetchall()]
postgis_template = getattr(settings, 'POSTGIS_TEMPLATE', 'template_postgis')
-
- if postgis_template in db_names:
- qn = self.connection.ops.quote_name
- return ' TEMPLATE %s' % qn(postgis_template)
- elif self.connection.ops.spatial_version < (2, 0):
- raise ImproperlyConfigured("Template database '%s' does not exist." % postgis_template)
- else:
- return ''
+ return ' TEMPLATE %s' % self.connection.ops.quote_name(postgis_template)

@jbronn:

On PostGIS 2.0, the recommended way to create a spatial database is to use CREATE EXTENSION instead of using a template database.

If we still require a template database, we should at least note that in the documentation.

ref: https://code.djangoproject.com/ticket/16455#comment:23

I wrote a patch the reintroduce the query, but it does it just once at instantiation time.

#439

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
View
23 django/contrib/gis/db/backends/postgis/operations.py
@@ -103,11 +103,12 @@ def __init__(self, connection):
self.geom_func_prefix = prefix
self.spatial_version = version
except DatabaseError:
- raise ImproperlyConfigured('Cannot determine PostGIS version for database "%s". '
- 'GeoDjango requires at least PostGIS version 1.3. '
- 'Was the database created from a spatial database '
- 'template?' % self.connection.settings_dict['NAME']
- )
+ raise ImproperlyConfigured(
+ 'Cannot determine PostGIS version for database "%s". '
+ 'GeoDjango requires at least PostGIS version 1.3. '
+ 'Was the database created from a spatial database '
+ 'template?' % self.connection.settings_dict['NAME']
+ )
# TODO: Raise helpful exceptions as they become known.
# PostGIS-specific operators. The commented descriptions of these
@@ -215,6 +216,10 @@ def get_dist_ops(operator):
'bboverlaps' : PostGISOperator('&&'),
}
+ # Native geometry type support added in PostGIS 2.0.
+ if version >= (2, 0, 0):
+ self.geometry = True
+
# Creating a dictionary lookup of all GIS terms for PostGIS.
gis_terms = ['isnull']
gis_terms += list(self.geometry_operators)
@@ -320,6 +325,14 @@ def geo_db_type(self, f):
'only with an SRID of 4326.')
return 'geography(%s,%d)'% (f.geom_type, f.srid)
+ elif self.geometry:
+ # Postgis 2.0 supports 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
View
2  django/contrib/gis/db/models/fields.py
@@ -95,7 +95,7 @@ def __init__(self, verbose_name=None, srid=4326, spatial_index=True, dim=2,
# Is this a geography rather than a geometry column?
self.geography = geography
- # Oracle-specific private attributes for creating the entrie in
+ # Oracle-specific private attributes for creating the entry in
# `USER_SDO_GEOM_METADATA`
self._extent = kwargs.pop('extent', (-180.0, -90.0, 180.0, 90.0))
self._tolerance = kwargs.pop('tolerance', 0.05)
Please sign in to comment.
Something went wrong with that request. Please try again.