summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2014-12-06 11:05:54 +0100
committerClaude Paroz <claude@2xlibre.net>2014-12-08 22:22:53 +0100
commit8f97413faed5431713c034897cda486507bf0cc3 (patch)
treeaecb4904bc44ba0bea216be8c7009dc884a252fe
parent1aa41dd000e0779c8b1de1f8e7aa4a0f2f752655 (diff)
Fixed #20968 -- Checked Spatialite metadata before migrations
Thanks Kenial S. Lee for the initial patch and Tim Graham for the review.
-rw-r--r--django/contrib/gis/db/backends/spatialite/base.py9
-rw-r--r--django/contrib/gis/db/backends/spatialite/creation.py8
-rw-r--r--django/core/management/commands/migrate.py2
-rw-r--r--django/db/backends/__init__.py7
-rw-r--r--django/db/backends/creation.py8
-rw-r--r--docs/ref/contrib/gis/install/spatialite.txt35
6 files changed, 24 insertions, 45 deletions
diff --git a/django/contrib/gis/db/backends/spatialite/base.py b/django/contrib/gis/db/backends/spatialite/base.py
index e51ffbef3a..63efb3ac61 100644
--- a/django/contrib/gis/db/backends/spatialite/base.py
+++ b/django/contrib/gis/db/backends/spatialite/base.py
@@ -79,3 +79,12 @@ class DatabaseWrapper(SQLiteDatabaseWrapper):
six.reraise(ImproperlyConfigured, ImproperlyConfigured(new_msg), sys.exc_info()[2])
cur.close()
return conn
+
+ def prepare_database(self):
+ super(DatabaseWrapper, self).prepare_database()
+ # Check if spatial metadata have been initialized in the database
+ with self.cursor() as cursor:
+ cursor.execute("PRAGMA table_info(geometry_columns);")
+ if cursor.fetchall() == []:
+ arg = "1" if self.features.supports_initspatialmetadata_in_one_transaction else ""
+ cursor.execute("SELECT InitSpatialMetaData(%s)" % arg)
diff --git a/django/contrib/gis/db/backends/spatialite/creation.py b/django/contrib/gis/db/backends/spatialite/creation.py
index 6c6ab98bfb..f1f40671d5 100644
--- a/django/contrib/gis/db/backends/spatialite/creation.py
+++ b/django/contrib/gis/db/backends/spatialite/creation.py
@@ -30,11 +30,3 @@ class SpatiaLiteCreation(DatabaseCreation):
style.SQL_FIELD(gqn(f.column)) + ');')
return output
-
- def _create_test_db_pre_migrate_sql(self):
- """
- Creates the spatial metadata tables.
- """
- cur = self.connection._cursor()
- arg = "1" if self.connection.features.supports_initspatialmetadata_in_one_transaction else ""
- cur.execute("SELECT InitSpatialMetaData(%s)" % arg)
diff --git a/django/core/management/commands/migrate.py b/django/core/management/commands/migrate.py
index 536afb0bb4..00732390aa 100644
--- a/django/core/management/commands/migrate.py
+++ b/django/core/management/commands/migrate.py
@@ -64,6 +64,8 @@ class Command(BaseCommand):
if options.get("list", False):
return self.show_migration_list(connection, [options['app_label']] if options['app_label'] else None)
+ # Hook for backends needing any database preparation
+ connection.prepare_database()
# Work out which apps have migrations and which do not
executor = MigrationExecutor(connection, self.migration_progress_callback)
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index fcdb742f85..64444297f3 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -432,6 +432,13 @@ class BaseDatabaseWrapper(object):
##### Miscellaneous #####
+ def prepare_database(self):
+ """
+ Hook to do any database check or preparation, generally called before
+ migrating a project or an app.
+ """
+ pass
+
@cached_property
def wrap_database_errors(self):
"""
diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
index cf48b92df1..18168deaca 100644
--- a/django/db/backends/creation.py
+++ b/django/db/backends/creation.py
@@ -371,8 +371,6 @@ class BaseDatabaseCreation(object):
settings.DATABASES[self.connection.alias]["NAME"] = test_database_name
self.connection.settings_dict["NAME"] = test_database_name
- self._create_test_db_pre_migrate_sql()
-
# We report migrate messages at one level lower than that requested.
# This ensures we don't get flooded with messages during testing
# (unless you really ask to be flooded).
@@ -398,12 +396,6 @@ class BaseDatabaseCreation(object):
return test_database_name
- def _create_test_db_pre_migrate_sql(self):
- """
- Hook for databases to load SQL before creating the test DB.
- """
- pass
-
def serialize_db_to_string(self):
"""
Serializes all data in the database into a JSON string.
diff --git a/docs/ref/contrib/gis/install/spatialite.txt b/docs/ref/contrib/gis/install/spatialite.txt
index d7508a4fee..05833496aa 100644
--- a/docs/ref/contrib/gis/install/spatialite.txt
+++ b/docs/ref/contrib/gis/install/spatialite.txt
@@ -211,34 +211,11 @@ following to your ``settings.py``::
Creating a spatial database for SpatiaLite
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-After you've installed SpatiaLite, you'll need to create a number of spatial
-metadata tables in your database in order to perform spatial queries.
+When running ``manage.py migrate`` with a SQLite or SpatiaLite database, the
+database file will be automatically created if it doesn't exist. Django will
+also ensure that the spatial metadata are initialized in the database.
-Use the ``spatialite`` utility to call the ``InitSpatialMetaData()`` function,
-like this::
+.. versionchanged:: 1.8
- $ spatialite geodjango.db "SELECT InitSpatialMetaData();"
- the SPATIAL_REF_SYS table already contains some row(s)
- InitSpatiaMetaData ()error:"table spatial_ref_sys already exists"
- 0
-
-You can safely ignore the error messages shown.
-
-.. note::
-
- The parameter ``geodjango.db`` is the *filename* of the SQLite database
- you want to use. Use the same in the :setting:`DATABASES` ``"name"`` key
- inside your ``settings.py``.
-
-.. note::
-
- When running ``manage.py migrate`` with a SQLite (or SpatiaLite) database,
- the database file will be automatically created if it doesn't exist. In
- this case, if your models contain any geometry columns, you'll see this
- error::
-
- CreateSpatialIndex() error: "no such table: geometry_columns"
-
- It's because the table creation queries are executed without spatial
- metadata tables. To avoid this, make the database file before executing
- ``manage.py migrate`` as described above.
+ Prior to Django 1.8, you had to intialize spatial metadata tables yourself
+ by manually running the "SELECT InitSpatialMetaData();" query.