From 894cb13779e6d092974c873bd2cf1452554d2e06 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Tue, 11 Dec 2018 03:06:24 -0500 Subject: [PATCH] Refs #29182 -- Stopped relying on legacy alter table semantic on SQLite 3.26+. SQLite 3.26 changed the behavior of table and column renaming operations to repoint foreign key references even if foreign key checks are disabled. This makes the workarounds in place to simulate this behavior unnecessary on SQLite 3.26+. Refs #30033. --- django/db/backends/sqlite3/features.py | 2 +- django/db/backends/sqlite3/schema.py | 10 +++++----- tests/backends/sqlite/tests.py | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/django/db/backends/sqlite3/features.py b/django/db/backends/sqlite3/features.py index aa24024f91..c61b0609d5 100644 --- a/django/db/backends/sqlite3/features.py +++ b/django/db/backends/sqlite3/features.py @@ -25,7 +25,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): supports_transactions = True atomic_transactions = False can_rollback_ddl = True - supports_atomic_references_rename = False + supports_atomic_references_rename = Database.version_info >= (3, 26, 0) supports_paramstyle_pyformat = False supports_sequence_reset = False can_clone_databases = True diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py index 7c3648cff2..3992d86651 100644 --- a/django/db/backends/sqlite3/schema.py +++ b/django/db/backends/sqlite3/schema.py @@ -27,13 +27,11 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): 'SQLite3 does not support disabling them in the middle of ' 'a multi-statement transaction.' ) - self.connection.cursor().execute('PRAGMA legacy_alter_table = ON') return super().__enter__() def __exit__(self, exc_type, exc_value, traceback): super().__exit__(exc_type, exc_value, traceback) self.connection.check_constraints() - self.connection.cursor().execute('PRAGMA legacy_alter_table = OFF') self.connection.enable_constraint_checking() def quote_value(self, value): @@ -84,11 +82,12 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): return False def alter_db_table(self, model, old_db_table, new_db_table, disable_constraints=True): - if disable_constraints and self._is_referenced_by_fk_constraint(old_db_table): + if (not self.connection.features.supports_atomic_references_rename and + disable_constraints and self._is_referenced_by_fk_constraint(old_db_table)): if self.connection.in_atomic_block: raise NotSupportedError(( 'Renaming the %r table while in a transaction is not ' - 'supported on SQLite because it would break referential ' + 'supported on SQLite < 3.26 because it would break referential ' 'integrity. Try adding `atomic = False` to the Migration class.' ) % old_db_table) self.connection.enable_constraint_checking() @@ -102,11 +101,12 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): table_name = model._meta.db_table _, old_column_name = old_field.get_attname_column() if (new_field.name != old_field_name and + not self.connection.features.supports_atomic_references_rename and self._is_referenced_by_fk_constraint(table_name, old_column_name, ignore_self=True)): if self.connection.in_atomic_block: raise NotSupportedError(( 'Renaming the %r.%r column while in a transaction is not ' - 'supported on SQLite because it would break referential ' + 'supported on SQLite < 3.26 because it would break referential ' 'integrity. Try adding `atomic = False` to the Migration class.' ) % (model._meta.db_table, old_field_name)) with atomic(self.connection.alias): diff --git a/tests/backends/sqlite/tests.py b/tests/backends/sqlite/tests.py index 46122dc38b..c5b9569eac 100644 --- a/tests/backends/sqlite/tests.py +++ b/tests/backends/sqlite/tests.py @@ -121,8 +121,8 @@ class SchemaTests(TransactionTestCase): new_field.set_attributes_from_name('renamed') msg = ( "Renaming the 'backends_author'.'name' column while in a " - "transaction is not supported on SQLite because it would break " - "referential integrity. Try adding `atomic = False` to the " + "transaction is not supported on SQLite < 3.26 because it would " + "break referential integrity. Try adding `atomic = False` to the " "Migration class." ) with self.assertRaisesMessage(NotSupportedError, msg): @@ -136,7 +136,7 @@ class SchemaTests(TransactionTestCase): """ msg = ( "Renaming the 'backends_author' table while in a transaction is " - "not supported on SQLite because it would break referential " + "not supported on SQLite < 3.26 because it would break referential " "integrity. Try adding `atomic = False` to the Migration class." ) with self.assertRaisesMessage(NotSupportedError, msg):