Fixed #24499 -- Dropped support for PostGIS 1.5.
This commit is contained in:
parent
faad6070ee
commit
26996e2d55
|
@ -1,10 +1,7 @@
|
||||||
from django.conf import settings
|
|
||||||
from django.db.backends.base.base import NO_DB_ALIAS
|
from django.db.backends.base.base import NO_DB_ALIAS
|
||||||
from django.db.backends.postgresql_psycopg2.base import \
|
from django.db.backends.postgresql_psycopg2.base import \
|
||||||
DatabaseWrapper as Psycopg2DatabaseWrapper
|
DatabaseWrapper as Psycopg2DatabaseWrapper
|
||||||
from django.utils.functional import cached_property
|
|
||||||
|
|
||||||
from .creation import PostGISCreation
|
|
||||||
from .features import DatabaseFeatures
|
from .features import DatabaseFeatures
|
||||||
from .introspection import PostGISIntrospection
|
from .introspection import PostGISIntrospection
|
||||||
from .operations import PostGISOperations
|
from .operations import PostGISOperations
|
||||||
|
@ -18,22 +15,11 @@ class DatabaseWrapper(Psycopg2DatabaseWrapper):
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
||||||
if kwargs.get('alias', '') != NO_DB_ALIAS:
|
if kwargs.get('alias', '') != NO_DB_ALIAS:
|
||||||
self.features = DatabaseFeatures(self)
|
self.features = DatabaseFeatures(self)
|
||||||
self.creation = PostGISCreation(self)
|
|
||||||
self.ops = PostGISOperations(self)
|
self.ops = PostGISOperations(self)
|
||||||
self.introspection = PostGISIntrospection(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):
|
def prepare_database(self):
|
||||||
super(DatabaseWrapper, self).prepare_database()
|
super(DatabaseWrapper, self).prepare_database()
|
||||||
if self.template_postgis is None:
|
# Check that postgis extension is installed.
|
||||||
# Check that postgis extension is installed on PostGIS >= 2
|
with self.cursor() as cursor:
|
||||||
with self.cursor() as cursor:
|
cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis")
|
||||||
cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis")
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
from django.db.backends.postgresql_psycopg2.creation import DatabaseCreation
|
|
||||||
|
|
||||||
|
|
||||||
class PostGISCreation(DatabaseCreation):
|
|
||||||
|
|
||||||
def sql_table_creation_suffix(self):
|
|
||||||
if self.connection.template_postgis is not None:
|
|
||||||
return ' TEMPLATE %s' % (
|
|
||||||
self.connection.ops.quote_name(self.connection.template_postgis),)
|
|
||||||
return ''
|
|
|
@ -110,6 +110,7 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
self.distance_spheroid = prefix + 'distance_spheroid'
|
self.distance_spheroid = prefix + 'distance_spheroid'
|
||||||
self.envelope = prefix + 'Envelope'
|
self.envelope = prefix + 'Envelope'
|
||||||
self.extent = prefix + 'Extent'
|
self.extent = prefix + 'Extent'
|
||||||
|
self.extent3d = prefix + '3DExtent'
|
||||||
self.force_rhr = prefix + 'ForceRHR'
|
self.force_rhr = prefix + 'ForceRHR'
|
||||||
self.geohash = prefix + 'GeoHash'
|
self.geohash = prefix + 'GeoHash'
|
||||||
self.geojson = prefix + 'AsGeoJson'
|
self.geojson = prefix + 'AsGeoJson'
|
||||||
|
@ -117,12 +118,14 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
self.intersection = prefix + 'Intersection'
|
self.intersection = prefix + 'Intersection'
|
||||||
self.kml = prefix + 'AsKML'
|
self.kml = prefix + 'AsKML'
|
||||||
self.length = prefix + 'Length'
|
self.length = prefix + 'Length'
|
||||||
|
self.length3d = prefix + '3DLength'
|
||||||
self.length_spheroid = prefix + 'length_spheroid'
|
self.length_spheroid = prefix + 'length_spheroid'
|
||||||
self.makeline = prefix + 'MakeLine'
|
self.makeline = prefix + 'MakeLine'
|
||||||
self.mem_size = prefix + 'mem_size'
|
self.mem_size = prefix + 'mem_size'
|
||||||
self.num_geom = prefix + 'NumGeometries'
|
self.num_geom = prefix + 'NumGeometries'
|
||||||
self.num_points = prefix + 'npoints'
|
self.num_points = prefix + 'npoints'
|
||||||
self.perimeter = prefix + 'Perimeter'
|
self.perimeter = prefix + 'Perimeter'
|
||||||
|
self.perimeter3d = prefix + '3DPerimeter'
|
||||||
self.point_on_surface = prefix + 'PointOnSurface'
|
self.point_on_surface = prefix + 'PointOnSurface'
|
||||||
self.polygonize = prefix + 'Polygonize'
|
self.polygonize = prefix + 'Polygonize'
|
||||||
self.reverse = prefix + 'Reverse'
|
self.reverse = prefix + 'Reverse'
|
||||||
|
@ -135,34 +138,6 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
self.union = prefix + 'Union'
|
self.union = prefix + 'Union'
|
||||||
self.unionagg = 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
|
@cached_property
|
||||||
def spatial_version(self):
|
def spatial_version(self):
|
||||||
"""Determine the version of the PostGIS library."""
|
"""Determine the version of the PostGIS library."""
|
||||||
|
@ -180,7 +155,7 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
except ProgrammingError:
|
except ProgrammingError:
|
||||||
raise ImproperlyConfigured(
|
raise ImproperlyConfigured(
|
||||||
'Cannot determine PostGIS version for database "%s". '
|
'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 '
|
'Was the database created from a spatial database '
|
||||||
'template?' % self.connection.settings_dict['NAME']
|
'template?' % self.connection.settings_dict['NAME']
|
||||||
)
|
)
|
||||||
|
@ -234,16 +209,14 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
raise NotImplementedError('PostGIS only supports geography columns with an SRID of 4326.')
|
raise NotImplementedError('PostGIS only supports geography columns with an SRID of 4326.')
|
||||||
|
|
||||||
return 'geography(%s,%d)' % (f.geom_type, f.srid)
|
return 'geography(%s,%d)' % (f.geom_type, f.srid)
|
||||||
elif self.geometry:
|
else:
|
||||||
# Postgis 2.0 supports type-based geometries.
|
# Type-based geometries.
|
||||||
# TODO: Support 'M' extension.
|
# TODO: Support 'M' extension.
|
||||||
if f.dim == 3:
|
if f.dim == 3:
|
||||||
geom_type = f.geom_type + 'Z'
|
geom_type = f.geom_type + 'Z'
|
||||||
else:
|
else:
|
||||||
geom_type = f.geom_type
|
geom_type = f.geom_type
|
||||||
return 'geometry(%s,%d)' % (geom_type, f.srid)
|
return 'geometry(%s,%d)' % (geom_type, f.srid)
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_distance(self, f, dist_val, lookup_type):
|
def get_distance(self, f, dist_val, lookup_type):
|
||||||
"""
|
"""
|
||||||
|
@ -253,7 +226,7 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
This is the most complex implementation of the spatial backends due to
|
This is the most complex implementation of the spatial backends due to
|
||||||
what is supported on geodetic geometry columns vs. what's available on
|
what is supported on geodetic geometry columns vs. what's available on
|
||||||
projected geometry columns. In addition, it has to take into account
|
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.
|
# Getting the distance parameter and any options.
|
||||||
if len(dist_val) == 1:
|
if len(dist_val) == 1:
|
||||||
|
|
|
@ -3,12 +3,8 @@ from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor
|
||||||
|
|
||||||
class PostGISSchemaEditor(DatabaseSchemaEditor):
|
class PostGISSchemaEditor(DatabaseSchemaEditor):
|
||||||
geom_index_type = 'GIST'
|
geom_index_type = 'GIST'
|
||||||
geom_index_ops = 'GIST_GEOMETRY_OPS'
|
|
||||||
geom_index_ops_nd = 'GIST_GEOMETRY_OPS_ND'
|
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_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"
|
sql_clear_geometry_columns = "DELETE FROM geometry_columns WHERE f_table_name = %(table)s"
|
||||||
|
|
||||||
|
@ -24,48 +20,21 @@ class PostGISSchemaEditor(DatabaseSchemaEditor):
|
||||||
if not isinstance(field, GeometryField):
|
if not isinstance(field, GeometryField):
|
||||||
return super(PostGISSchemaEditor, self).column_sql(model, field, include_default)
|
return super(PostGISSchemaEditor, self).column_sql(model, field, include_default)
|
||||||
|
|
||||||
if field.geography or self.connection.ops.geometry:
|
column_sql = super(PostGISSchemaEditor, self).column_sql(model, field, include_default)
|
||||||
# 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),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if field.spatial_index:
|
if field.spatial_index:
|
||||||
# Spatial indexes created the same way for both Geometry and
|
# Spatial indexes created the same way for both Geometry and
|
||||||
# Geography columns.
|
# 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:
|
if field.geography:
|
||||||
index_ops = ''
|
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:
|
if field.dim > 2:
|
||||||
index_ops = self.geom_index_ops_nd
|
index_ops = self.geom_index_ops_nd
|
||||||
else:
|
else:
|
||||||
index_ops = ''
|
index_ops = ''
|
||||||
else:
|
|
||||||
index_ops = self.geom_index_ops
|
|
||||||
self.geometry_sql.append(
|
self.geometry_sql.append(
|
||||||
self.sql_add_spatial_index % {
|
self.sql_add_spatial_index % {
|
||||||
"index": self.quote_name('%s_%s_id' % (model._meta.db_table, field.column)),
|
"index": self.quote_name('%s_%s_id' % (model._meta.db_table, field.column)),
|
||||||
|
@ -96,17 +65,3 @@ class PostGISSchemaEditor(DatabaseSchemaEditor):
|
||||||
for sql in self.geometry_sql:
|
for sql in self.geometry_sql:
|
||||||
self.execute(sql)
|
self.execute(sql)
|
||||||
self.geometry_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),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
|
@ -462,8 +462,8 @@ class BaseDatabaseSchemaEditor(object):
|
||||||
(new_type is None and new_field.remote_field is None)):
|
(new_type is None and new_field.remote_field is None)):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Cannot alter field %s into %s - they do not properly define "
|
"Cannot alter field %s into %s - they do not properly define "
|
||||||
"db_type (are you using PostGIS 1.5 or badly-written custom "
|
"db_type (are you using a badly-written custom field?)" %
|
||||||
"fields?)" % (old_field, new_field),
|
(old_field, new_field),
|
||||||
)
|
)
|
||||||
elif old_type is None and new_type is None and (
|
elif old_type is None and new_type is None and (
|
||||||
old_field.remote_field.through and new_field.remote_field.through and
|
old_field.remote_field.through and new_field.remote_field.through and
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
if [[ `uname -r | grep el6` ]]; then
|
|
||||||
POSTGIS_SQL_PATH=`pg_config --sharedir`/contrib/postgis
|
|
||||||
POSTGIS_SQL_FILE=$POSTGIS_SQL_PATH/postgis-64.sql
|
|
||||||
else
|
|
||||||
POSTGIS_SQL_PATH=`pg_config --sharedir`/contrib/postgis-1.5
|
|
||||||
POSTGIS_SQL_FILE=$POSTGIS_SQL_PATH/postgis.sql
|
|
||||||
fi
|
|
||||||
createdb -E UTF8 template_postgis # Create the template spatial database.
|
|
||||||
createlang -d template_postgis plpgsql # Adding PLPGSQL language support.
|
|
||||||
psql -d postgres -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis';"
|
|
||||||
psql -d template_postgis -f $POSTGIS_SQL_FILE # Loading the PostGIS SQL routines
|
|
||||||
psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" # Enabling users to alter spatial tables.
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON geography_columns TO PUBLIC;"
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;"
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
POSTGIS_SQL=postgis.sql
|
|
||||||
|
|
||||||
# For Ubuntu 11.10, 12.04 / Linux Mint 12 (with PostGIS 1.5)
|
|
||||||
if [ -d "/usr/share/postgresql/9.1/contrib/postgis-1.5" ]
|
|
||||||
then
|
|
||||||
POSTGIS_SQL_PATH=/usr/share/postgresql/9.1/contrib/postgis-1.5
|
|
||||||
fi
|
|
||||||
|
|
||||||
createdb -E UTF8 template_postgis && \
|
|
||||||
( createlang -d template_postgis -l | grep plpgsql || createlang -d template_postgis plpgsql ) && \
|
|
||||||
psql -d postgres -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis';" && \
|
|
||||||
psql -d template_postgis -f $POSTGIS_SQL_PATH/$POSTGIS_SQL && \
|
|
||||||
psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql && \
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" && \
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;"
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON geography_columns TO PUBLIC;"
|
|
|
@ -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
|
`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:`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
|
: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
|
`SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.1, 4.0, 3.0, 2.4
|
||||||
======================== ==================================== ================================ ============================
|
======================== ==================================== ================================ ============================
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ totally fine with GeoDjango. Your mileage may vary.
|
||||||
GDAL 1.9.0 2012-01-03
|
GDAL 1.9.0 2012-01-03
|
||||||
GDAL 1.10.0 2013-04-29
|
GDAL 1.10.0 2013-04-29
|
||||||
GDAL 1.11.0 2014-04-25
|
GDAL 1.11.0 2014-04-25
|
||||||
PostGIS 1.5.0 2010-02-04
|
|
||||||
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
|
||||||
Spatialite 2.4.0 2010-11-14
|
Spatialite 2.4.0 2010-11-14
|
||||||
|
|
|
@ -43,8 +43,7 @@ Finally, make and install::
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
GeoDjango does not automatically create a spatial database. Please consult
|
GeoDjango does not automatically create a spatial database. Please consult
|
||||||
the section on :ref:`spatialdb_template91` or
|
the section on :ref:`spatialdb_template91` for more information.
|
||||||
:ref:`spatialdb_template_earlier` for more information.
|
|
||||||
|
|
||||||
__ http://postgis.net/
|
__ http://postgis.net/
|
||||||
|
|
||||||
|
@ -54,8 +53,8 @@ Post-installation
|
||||||
.. _spatialdb_template:
|
.. _spatialdb_template:
|
||||||
.. _spatialdb_template91:
|
.. _spatialdb_template91:
|
||||||
|
|
||||||
Creating a spatial database with PostGIS 2.0 and PostgreSQL 9.1+
|
Creating a spatial database
|
||||||
----------------------------------------------------------------
|
---------------------------
|
||||||
|
|
||||||
PostGIS 2 includes an extension for Postgres 9.1+ that can be used to enable
|
PostGIS 2 includes an extension for Postgres 9.1+ that can be used to enable
|
||||||
spatial functionality::
|
spatial functionality::
|
||||||
|
@ -77,94 +76,6 @@ __ http://postgis.net/docs/Topology.html
|
||||||
the :djadmin:`migrate` process. You can still create it manually if you
|
the :djadmin:`migrate` process. You can still create it manually if you
|
||||||
wish.
|
wish.
|
||||||
|
|
||||||
.. _spatialdb_template_earlier:
|
|
||||||
|
|
||||||
Creating a spatial database template for earlier versions
|
|
||||||
---------------------------------------------------------
|
|
||||||
|
|
||||||
If you have an earlier version of PostGIS or PostgreSQL, the CREATE
|
|
||||||
EXTENSION isn't available and you need to create the spatial database
|
|
||||||
using the following instructions.
|
|
||||||
|
|
||||||
Creating a spatial database with PostGIS is different than normal because
|
|
||||||
additional SQL must be loaded to enable spatial functionality. Because of
|
|
||||||
the steps in this process, it's better to create a database template that
|
|
||||||
can be reused later.
|
|
||||||
|
|
||||||
First, you need to be able to execute the commands as a privileged database
|
|
||||||
user. For example, you can use the following to become the ``postgres`` user::
|
|
||||||
|
|
||||||
$ sudo su - postgres
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
The location *and* name of the PostGIS SQL files (e.g., from
|
|
||||||
``POSTGIS_SQL_PATH`` below) depends on the version of PostGIS.
|
|
||||||
Version 1.5 uses ``<sharedir>/contrib/postgis-1.5/postgis.sql``.
|
|
||||||
|
|
||||||
To complicate matters, Debian/Ubuntu distributions have their own separate
|
|
||||||
directory naming system that might change with time. In this case, use the
|
|
||||||
:download:`create_template_postgis-debian.sh` script.
|
|
||||||
|
|
||||||
The example below assumes PostGIS 1.5, thus you may need to modify
|
|
||||||
``POSTGIS_SQL_PATH`` and the name of the SQL file for the specific
|
|
||||||
version of PostGIS you are using.
|
|
||||||
|
|
||||||
Once you're a database super user, then you may execute the following commands
|
|
||||||
to create a PostGIS spatial database template::
|
|
||||||
|
|
||||||
$ POSTGIS_SQL_PATH=`pg_config --sharedir`/contrib/postgis-2.0
|
|
||||||
# Creating the template spatial database.
|
|
||||||
$ createdb -E UTF8 template_postgis
|
|
||||||
$ createlang -d template_postgis plpgsql # Adding PLPGSQL language support.
|
|
||||||
# Allows non-superusers the ability to create from this template
|
|
||||||
$ psql -d postgres -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis';"
|
|
||||||
# Loading the PostGIS SQL routines
|
|
||||||
$ psql -d template_postgis -f $POSTGIS_SQL_PATH/postgis.sql
|
|
||||||
$ psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql
|
|
||||||
# Enabling users to alter spatial tables.
|
|
||||||
$ psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;"
|
|
||||||
$ psql -d template_postgis -c "GRANT ALL ON geography_columns TO PUBLIC;"
|
|
||||||
$ psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;"
|
|
||||||
|
|
||||||
These commands may be placed in a shell script for later use; for convenience
|
|
||||||
the following scripts are available:
|
|
||||||
|
|
||||||
=============== =============================================
|
|
||||||
PostGIS version Bash shell script
|
|
||||||
=============== =============================================
|
|
||||||
1.5 :download:`create_template_postgis-1.5.sh`
|
|
||||||
Debian/Ubuntu :download:`create_template_postgis-debian.sh`
|
|
||||||
=============== =============================================
|
|
||||||
|
|
||||||
Afterwards, you may create a spatial database by simply specifying
|
|
||||||
``template_postgis`` as the template to use (via the ``-T`` option)::
|
|
||||||
|
|
||||||
$ createdb -T template_postgis <db name>
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
While the ``createdb`` command does not require database super-user privileges,
|
|
||||||
it must be executed by a database user that has permissions to create databases.
|
|
||||||
You can create such a user with the following command::
|
|
||||||
|
|
||||||
$ createuser --createdb <user>
|
|
||||||
|
|
||||||
PostgreSQL's createdb fails
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
When the PostgreSQL cluster uses a non-UTF8 encoding, the
|
|
||||||
:file:`create_template_postgis-*.sh` script will fail when executing
|
|
||||||
``createdb``::
|
|
||||||
|
|
||||||
createdb: database creation failed: ERROR: new encoding (UTF8) is incompatible
|
|
||||||
with the encoding of the template database (SQL_ASCII)
|
|
||||||
|
|
||||||
The `current workaround`__ is to re-create the cluster using UTF8 (back up any
|
|
||||||
databases before dropping the cluster).
|
|
||||||
|
|
||||||
__ http://jacobian.org/writing/pg-encoding-ubuntu/
|
|
||||||
|
|
||||||
Managing the database
|
Managing the database
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
@ -175,4 +86,4 @@ For example, to create a ``geodjango`` spatial database and user, the following
|
||||||
may be executed from the SQL Shell as the ``postgres`` user::
|
may be executed from the SQL Shell as the ``postgres`` user::
|
||||||
|
|
||||||
postgres# CREATE USER geodjango PASSWORD 'my_passwd';
|
postgres# CREATE USER geodjango PASSWORD 'my_passwd';
|
||||||
postgres# CREATE DATABASE geodjango OWNER geodjango TEMPLATE template_postgis ENCODING 'utf8';
|
postgres# CREATE DATABASE geodjango OWNER geodjango;
|
||||||
|
|
|
@ -17,16 +17,6 @@ Settings
|
||||||
|
|
||||||
The settings below have sensible defaults, and shouldn't require manual setting.
|
The settings below have sensible defaults, and shouldn't require manual setting.
|
||||||
|
|
||||||
.. setting:: POSTGIS_TEMPLATE
|
|
||||||
|
|
||||||
``POSTGIS_TEMPLATE``
|
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
This setting may be used to customize the name of the PostGIS template
|
|
||||||
database to use. It automatically defaults to ``'template_postgis'``
|
|
||||||
(the same name used in the
|
|
||||||
:ref:`installation documentation <spatialdb_template>`).
|
|
||||||
|
|
||||||
.. setting:: POSTGIS_VERSION
|
.. setting:: POSTGIS_VERSION
|
||||||
|
|
||||||
``POSTGIS_VERSION``
|
``POSTGIS_VERSION``
|
||||||
|
@ -80,15 +70,6 @@ is done from an existing superuser account)::
|
||||||
|
|
||||||
postgres# ALTER ROLE <user_name> SUPERUSER;
|
postgres# ALTER ROLE <user_name> SUPERUSER;
|
||||||
|
|
||||||
Create a database using PostGIS version 2
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
When testing projects using :ref:`PostGIS 2 <spatialdb_template91>`,
|
|
||||||
the test database is created using the ``CREATE EXTENSION postgis``
|
|
||||||
instruction, provided that no template ``template_postgis`` (or named
|
|
||||||
accordingly to :setting:`POSTGIS_TEMPLATE`) exists in the current
|
|
||||||
database.
|
|
||||||
|
|
||||||
Windows
|
Windows
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -308,12 +308,6 @@ This command should produce the following output:
|
||||||
CREATE INDEX "world_worldborder_mpoly_id" ON "world_worldborder" USING GIST ( "mpoly" );
|
CREATE INDEX "world_worldborder_mpoly_id" ON "world_worldborder" USING GIST ( "mpoly" );
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
With PostGIS < 2.0, the output is slightly different. The ``mpoly`` geometry
|
|
||||||
column is added through a separate ``SELECT AddGeometryColumn(...)``
|
|
||||||
statement.
|
|
||||||
|
|
||||||
If this looks correct, run :djadmin:`migrate` to create this table in the
|
If this looks correct, run :djadmin:`migrate` to create this table in the
|
||||||
database:
|
database:
|
||||||
|
|
||||||
|
|
|
@ -418,6 +418,8 @@ Miscellaneous
|
||||||
backwards incompatible if you have overridden the ``get_context_data()``
|
backwards incompatible if you have overridden the ``get_context_data()``
|
||||||
method without calling ``super()``.
|
method without calling ``super()``.
|
||||||
|
|
||||||
|
* Support for PostGIS 1.5 has been dropped.
|
||||||
|
|
||||||
.. _deprecated-features-1.9:
|
.. _deprecated-features-1.9:
|
||||||
|
|
||||||
Features deprecated in 1.9
|
Features deprecated in 1.9
|
||||||
|
|
|
@ -696,12 +696,8 @@ class GeoQuerySetTest(TestCase):
|
||||||
|
|
||||||
for c in City.objects.filter(point__isnull=False).num_geom():
|
for c in City.objects.filter(point__isnull=False).num_geom():
|
||||||
# Oracle and PostGIS 2.0+ will return 1 for the number of
|
# Oracle and PostGIS 2.0+ will return 1 for the number of
|
||||||
# geometries on non-collections, whereas PostGIS < 2.0.0
|
# geometries on non-collections.
|
||||||
# will return None.
|
self.assertEqual(1, c.num_geom)
|
||||||
if postgis and connection.ops.spatial_version < (2, 0, 0):
|
|
||||||
self.assertIsNone(c.num_geom)
|
|
||||||
else:
|
|
||||||
self.assertEqual(1, c.num_geom)
|
|
||||||
|
|
||||||
@skipUnlessDBFeature("supports_num_points_poly")
|
@skipUnlessDBFeature("supports_num_points_poly")
|
||||||
def test_num_points(self):
|
def test_num_points(self):
|
||||||
|
|
Loading…
Reference in New Issue