#36170: Running no-op migrations (verbose_name, ...) slow on sqlite
--------------------------------------+------------------------------------
Reporter: Klaas van Schelven | Owner: (none)
Type: Cleanup/optimization | Status: new
Component: Migrations | Version: 5.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by Simon Charette):
* stage: Unreviewed => Accepted
Comment:
Interesting use case. I think it's worth a shot but we should definitely
error on the side of caution here as to avoid causing subtle integrity
violation regressions. That is the `PRAGMA foreign_key_check` might be
necessary for other operations that SQLite added support for over the
years such as `ADD FIELD` assuming it's a foreign key that can be
populated with invalid data.
I believe the following should cover all no-op migrations while avoiding
the daunting task of figuring out for which operations are safe to skip
foreign key checks for
{{{#!diff
diff --git a/django/db/backends/sqlite3/schema.py
b/django/db/backends/sqlite3/schema.py
index 3617d17fac..a74c010384 100644
--- a/django/db/backends/sqlite3/schema.py
+++ b/django/db/backends/sqlite3/schema.py
@@ -33,13 +33,23 @@ def __enter__(self):
"SQLite does not support disabling them in the middle of
"
"a multi-statement transaction."
)
+ # Avoid checking foreign key constraint for no-op migrations that
+ # don't execute SQL as it can be expensive on large databases.
+ self.must_check_constraints = False
return super().__enter__()
def __exit__(self, exc_type, exc_value, traceback):
- self.connection.check_constraints()
+ if self.must_check_constraints:
+ self.connection.check_constraints()
super().__exit__(exc_type, exc_value, traceback)
self.connection.enable_constraint_checking()
+ def execute(self, *args, **kwargs):
+ # Execution of any SQL results in a subsequent foreign key
constraint
+ # check to account for them being disabled during schema
alteration.
+ self.must_check_constraints = True
+ return super().execute(*args, **kwargs)
+
def quote_value(self, value):
# The backend "mostly works" without this function and there are
use
# cases for compiling Python without the sqlite3 libraries (e.g.
}}}
Does that sound like a reasonable compromise?
--
Ticket URL: <
https://code.djangoproject.com/ticket/36170#comment:2>