From bac7664f274be834a09e037331889959f04a75e7 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sat, 6 Dec 2014 15:11:20 +0100 Subject: [PATCH] Ran 'CREATE EXTENSION postgis' during prepare_database hook DatabaseWrapper.prepare_database has been introduced in 307de67073. --- .../contrib/gis/db/backends/postgis/base.py | 19 ++++++++++++ .../gis/db/backends/postgis/creation.py | 29 ++----------------- docs/ref/contrib/gis/install/postgis.txt | 6 ++++ docs/releases/1.8.txt | 4 +++ 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/django/contrib/gis/db/backends/postgis/base.py b/django/contrib/gis/db/backends/postgis/base.py index 338748bc4a4..12ed955dc2c 100644 --- a/django/contrib/gis/db/backends/postgis/base.py +++ b/django/contrib/gis/db/backends/postgis/base.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.db.backends.creation import NO_DB_ALIAS from django.db.backends.postgresql_psycopg2.base import ( DatabaseWrapper as Psycopg2DatabaseWrapper, @@ -8,6 +9,7 @@ from django.contrib.gis.db.backends.postgis.creation import PostGISCreation from django.contrib.gis.db.backends.postgis.introspection import PostGISIntrospection from django.contrib.gis.db.backends.postgis.operations import PostGISOperations from django.contrib.gis.db.backends.postgis.schema import PostGISSchemaEditor +from django.utils.functional import cached_property class DatabaseFeatures(BaseSpatialFeatures, Psycopg2DatabaseFeatures): @@ -25,3 +27,20 @@ class DatabaseWrapper(Psycopg2DatabaseWrapper): 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.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") + cursor.connection.commit() diff --git a/django/contrib/gis/db/backends/postgis/creation.py b/django/contrib/gis/db/backends/postgis/creation.py index 8c9a27b8c53..464f3d6a55d 100644 --- a/django/contrib/gis/db/backends/postgis/creation.py +++ b/django/contrib/gis/db/backends/postgis/creation.py @@ -1,6 +1,4 @@ -from django.conf import settings from django.db.backends.postgresql_psycopg2.creation import DatabaseCreation -from django.utils.functional import cached_property class PostGISCreation(DatabaseCreation): @@ -8,15 +6,6 @@ class PostGISCreation(DatabaseCreation): geom_index_ops = 'GIST_GEOMETRY_OPS' geom_index_ops_nd = 'GIST_GEOMETRY_OPS_ND' - @cached_property - def template_postgis(self): - template_postgis = getattr(settings, 'POSTGIS_TEMPLATE', 'template_postgis') - with self.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 sql_indexes_for_field(self, model, f, style): "Return any spatial index creation SQL for the field." from django.contrib.gis.db.models.fields import GeometryField @@ -77,21 +66,7 @@ class PostGISCreation(DatabaseCreation): return output def sql_table_creation_suffix(self): - if self.template_postgis is not None: + if self.connection.template_postgis is not None: return ' TEMPLATE %s' % ( - self.connection.ops.quote_name(self.template_postgis),) + self.connection.ops.quote_name(self.connection.template_postgis),) return '' - - def _create_test_db(self, verbosity, autoclobber, keepdb=False): - test_database_name = super(PostGISCreation, self)._create_test_db(verbosity, autoclobber, keepdb) - if keepdb: - return test_database_name - if self.template_postgis is None: - # Connect to the test database in order to create the postgis extension - self.connection.close() - self.connection.settings_dict["NAME"] = test_database_name - with self.connection.cursor() as cursor: - cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis") - cursor.connection.commit() - - return test_database_name diff --git a/docs/ref/contrib/gis/install/postgis.txt b/docs/ref/contrib/gis/install/postgis.txt index e9c611aa313..ab7da318617 100644 --- a/docs/ref/contrib/gis/install/postgis.txt +++ b/docs/ref/contrib/gis/install/postgis.txt @@ -68,6 +68,12 @@ spatial functionality:: No PostGIS topology functionalities are yet available from GeoDjango, so the creation of the ``postgis_topology`` extension is entirely optional. +.. versionchanged:: 1.8 + + The ``CREATE EXTENSION postgis`` command is now automatically run during + the :djadmin:`migrate` process. You can still create it manually if you + wish. + .. _spatialdb_template_earlier: Creating a spatial database template for earlier versions diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 2ddcaf25bb3..a233edd4430 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -135,6 +135,10 @@ Minor features * The Spatialite backend now supports ``Collect`` and ``Extent`` aggregates when the database version is 3.0 or later. +* The PostGIS 2 ``CREATE EXTENSION postgis`` and the Spatialite + ``SELECT InitSpatialMetaData`` initialization commands are now automatically + run by :djadmin:`migrate`. + * Compatibility shims for ``SpatialRefSys`` and ``GeometryColumns`` changed in Django 1.2 have been removed.