diff --git a/django/contrib/gis/db/backends/postgis/creation.py b/django/contrib/gis/db/backends/postgis/creation.py index bad22bee70..06b60117f6 100644 --- a/django/contrib/gis/db/backends/postgis/creation.py +++ b/django/contrib/gis/db/backends/postgis/creation.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.core.exceptions import ImproperlyConfigured from django.db.backends.postgresql_psycopg2.creation import DatabaseCreation class PostGISCreation(DatabaseCreation): @@ -38,12 +39,20 @@ class PostGISCreation(DatabaseCreation): style.SQL_FIELD(qn(f.column)) + style.SQL_KEYWORD(' SET NOT NULL') + ';') - if f.spatial_index: # 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 f.geography: index_opts = '' + elif self.connection.ops.spatial_version >= (2, 0): + if f.dim > 2: + index_opts = ' ' + style.SQL_KEYWORD('gist_geometry_ops_nd') + else: + index_opts = '' else: index_opts = ' ' + style.SQL_KEYWORD(self.geom_index_opts) output.append(style.SQL_KEYWORD('CREATE INDEX ') + @@ -56,5 +65,15 @@ class PostGISCreation(DatabaseCreation): return output def sql_table_creation_suffix(self): - qn = self.connection.ops.quote_name - return ' TEMPLATE %s' % qn(getattr(settings, 'POSTGIS_TEMPLATE', 'template_postgis')) + 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 '' diff --git a/django/contrib/gis/tests/geoapp/tests.py b/django/contrib/gis/tests/geoapp/tests.py index 7fc870f64b..952ac9d45b 100644 --- a/django/contrib/gis/tests/geoapp/tests.py +++ b/django/contrib/gis/tests/geoapp/tests.py @@ -576,8 +576,8 @@ class GeoQuerySetTest(TestCase): for c in City.objects.filter(point__isnull=False).num_geom(): # Oracle will return 1 for the number of geometries on non-collections, # whereas PostGIS will return None. - if postgis: - self.assertEqual(None, 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) diff --git a/docs/ref/contrib/gis/install.txt b/docs/ref/contrib/gis/install.txt index d84ffc6b52..d66fd7ab77 100644 --- a/docs/ref/contrib/gis/install.txt +++ b/docs/ref/contrib/gis/install.txt @@ -63,7 +63,7 @@ supported versions, and any notes for each of the supported database backends: ================== ============================== ================== ========================================= Database Library Requirements Supported Versions Notes ================== ============================== ================== ========================================= -PostgreSQL GEOS, PROJ.4, PostGIS 8.1+ Requires PostGIS. +PostgreSQL GEOS, PROJ.4, PostGIS 8.2+ Requires PostGIS. MySQL GEOS 5.x Not OGC-compliant; limited functionality. Oracle GEOS 10.2, 11 XE not supported; not tested with 9. SQLite GEOS, GDAL, PROJ.4, SpatiaLite 3.6.+ Requires SpatiaLite 2.3+, pysqlite2 2.5+ @@ -88,7 +88,7 @@ Program Description Required `PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 4.8, 4.7, 4.6, 4.5, 4.4 :ref:`GDAL ` Geospatial Data Abstraction Library No (but, required for SQLite) 1.9, 1.8, 1.7, 1.6, 1.5 :ref:`GeoIP ` IP-based geolocation library No 1.4 -`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 1.5, 1.4, 1.3 +`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 2.0, 1.5, 1.4, 1.3 `SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 3.0, 2.4, 2.3 ======================== ==================================== ================================ ========================== @@ -226,45 +226,6 @@ Finally, configure, make and install PROJ.4:: $ sudo make install $ cd .. -.. _postgis: - -PostGIS -------- - -`PostGIS`__ adds geographic object support to PostgreSQL, turning it -into a spatial database. :ref:`geosbuild` and :ref:`proj4` should be -installed prior to building PostGIS. - -.. note:: - - The `psycopg2`_ module is required for use as the database adaptor - when using GeoDjango with PostGIS. - -.. _psycopg2: http://initd.org/psycopg/ - -First download the source archive, and extract:: - - $ wget http://postgis.refractions.net/download/postgis-1.5.5.tar.gz - $ tar xzf postgis-1.5.5.tar.gz - $ cd postgis-1.5.5 - -Next, configure, make and install PostGIS:: - - $ ./configure - -Finally, make and install:: - - $ make - $ sudo make install - $ cd .. - -.. note:: - - GeoDjango does not automatically create a spatial database. Please - consult the section on :ref:`spatialdb_template` for more information. - -__ http://postgis.refractions.net/ - .. _gdalbuild: GDAL @@ -364,6 +325,48 @@ file: SetEnv GDAL_DATA /usr/local/share +.. _postgis: + +PostGIS +------- + +`PostGIS`__ adds geographic object support to PostgreSQL, turning it +into a spatial database. :ref:`geosbuild`, :ref:`proj4` and +:ref:`gdalbuild` should be installed prior to building PostGIS. You +might also need additional libraries, see `PostGIS requirements`_. + +.. note:: + + The `psycopg2`_ module is required for use as the database adaptor + when using GeoDjango with PostGIS. + +.. _psycopg2: http://initd.org/psycopg/ +.. _PostGIS requirements: http://www.postgis.org/documentation/manual-2.0/postgis_installation.html#id2711662 + +First download the source archive, and extract:: + + $ wget http://postgis.refractions.net/download/postgis-2.0.1.tar.gz + $ tar xzf postgis-2.0.1.tar.gz + $ cd postgis-2.0.1 + +Next, configure, make and install PostGIS:: + + $ ./configure + +Finally, make and install:: + + $ make + $ sudo make install + $ cd .. + +.. note:: + + GeoDjango does not automatically create a spatial database. Please consult + the section on :ref:`spatialdb_template91` or + :ref:`spatialdb_template_earlier` for more information. + +__ http://postgis.refractions.net/ + .. _spatialite: SpatiaLite @@ -507,10 +510,27 @@ to build and install:: Post-installation ================= -.. _spatialdb_template: +.. _spatialdb_template91: -Creating a spatial database template for PostGIS ------------------------------------------------- +Creating a spatial database with PostGIS 2.0 and PostgreSQL 9.1 +--------------------------------------------------------------- + +PostGIS 2 includes an extension for Postgres 9.1 that can be used to enable +spatial functionality:: + + $ createdb + $ psql + > CREATE EXTENSION postgis; + > CREATE EXTENSION postgis_topology; + +.. _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 @@ -540,7 +560,7 @@ user. For example, you can use the following to become the ``postgres`` user:: 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-1.5 + $ 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. @@ -1083,7 +1103,7 @@ Afterwards, the ``/etc/init.d/postgresql-8.3`` script should be used to manage the starting and stopping of PostgreSQL. In addition, the SQL files for PostGIS are placed in a different location on -Debian 5.0 . Thus when :ref:`spatialdb_template` either: +Debian 5.0 . Thus when :ref:`spatialdb_template_earlier` either: * Create a symbolic link to these files: diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt index c39592122b..41fb2882a7 100644 --- a/docs/releases/1.5.txt +++ b/docs/releases/1.5.txt @@ -119,7 +119,8 @@ GeoDjango * The wkb and hex properties of `GEOSGeometry` objects preserve the Z dimension. -* Support for GDAL < 1.5 has been dropped. +* Support for PostGIS 2.0 has been added and support for GDAL < 1.5 has been + dropped. Minor features ~~~~~~~~~~~~~~