summaryrefslogtreecommitdiff
path: root/django/db/backends/sqlite3
diff options
context:
space:
mode:
Diffstat (limited to 'django/db/backends/sqlite3')
-rw-r--r--django/db/backends/sqlite3/base.py12
-rw-r--r--django/db/backends/sqlite3/schema.py11
2 files changed, 16 insertions, 7 deletions
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 6ead2b2d48..9b0be56862 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -215,11 +215,13 @@ class DatabaseWrapper(BaseDatabaseWrapper):
self.connection.isolation_level = level
def disable_constraint_checking(self):
- if self.in_atomic_block:
- # sqlite3 cannot disable constraint checking inside a transaction.
- return False
- self.cursor().execute('PRAGMA foreign_keys = OFF')
- return True
+ with self.cursor() as cursor:
+ cursor.execute('PRAGMA foreign_keys = OFF')
+ # Foreign key constraints cannot be turned off while in a multi-
+ # statement transaction. Fetch the current state of the pragma
+ # to determine if constraints are effectively disabled.
+ enabled = cursor.execute('PRAGMA foreign_keys').fetchone()[0]
+ return not bool(enabled)
def enable_constraint_checking(self):
self.cursor().execute('PRAGMA foreign_keys = ON')
diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py
index e0d8135cbd..0954c66aaf 100644
--- a/django/db/backends/sqlite3/schema.py
+++ b/django/db/backends/sqlite3/schema.py
@@ -19,8 +19,15 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
def __enter__(self):
# Some SQLite schema alterations need foreign key constraints to be
- # disabled. Enforce it here for the duration of the transaction.
- self.connection.disable_constraint_checking()
+ # disabled. Enforce it here for the duration of the schema edition.
+ if not self.connection.disable_constraint_checking():
+ raise NotSupportedError(
+ 'SQLite schema editor cannot be used while foreign key '
+ 'constraint checks are enabled. Make sure to disable them '
+ 'before entering a transaction.atomic() context because '
+ '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__()