mirror of https://github.com/django/django.git
Fixed #20968 -- Checked Spatialite metadata before migrations
Thanks Kenial S. Lee for the initial patch.
This commit is contained in:
parent
e309135081
commit
307de67073
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue