summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Bronn <jbronn@gmail.com>2012-10-06 09:57:24 -0700
committerJustin Bronn <jbronn@gmail.com>2012-10-06 09:57:24 -0700
commit91ef2a5253a50a602523bdda943c32c4cfe719fe (patch)
tree328798c07d13a5330cc2340dea5d10fdf11d3507
parentb6b8a3f66b5cf4f00bd7ce668ac04f21bb73e0b9 (diff)
Use native geometry types on PostGIS 2.0+ instead of `AddGeometryColumn` and don't query database in `PostGISCreation.sql_table_creation_suffix`.
-rw-r--r--django/contrib/gis/db/backends/base.py3
-rw-r--r--django/contrib/gis/db/backends/postgis/creation.py32
-rw-r--r--django/contrib/gis/db/backends/postgis/operations.py23
-rw-r--r--django/contrib/gis/db/models/fields.py2
4 files changed, 33 insertions, 27 deletions
diff --git a/django/contrib/gis/db/backends/base.py b/django/contrib/gis/db/backends/base.py
index 0bd598997c..171a304439 100644
--- a/django/contrib/gis/db/backends/base.py
+++ b/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
diff --git a/django/contrib/gis/db/backends/postgis/creation.py b/django/contrib/gis/db/backends/postgis/creation.py
index 06b60117f6..406dc4e487 100644
--- a/django/contrib/gis/db/backends/postgis/creation.py
+++ b/django/contrib/gis/db/backends/postgis/creation.py
@@ -4,7 +4,8 @@ from django.db.backends.postgresql_psycopg2.creation import DatabaseCreation
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 @@ class PostGISCreation(DatabaseCreation):
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 @@ class PostGISCreation(DatabaseCreation):
# 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)
diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py
index ff9110de01..aa23b974db 100644
--- a/django/contrib/gis/db/backends/postgis/operations.py
+++ b/django/contrib/gis/db/backends/postgis/operations.py
@@ -103,11 +103,12 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
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 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
'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 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
'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
diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py
index c8b8901d59..d90ce309d4 100644
--- a/django/contrib/gis/db/models/fields.py
+++ b/django/contrib/gis/db/models/fields.py
@@ -95,7 +95,7 @@ class GeometryField(Field):
# 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)