Fix restoring table indexes when rebuilding a table on SQLite.

Review Request #11082 — Created July 16, 2020 and submitted

Information

Django Evolution
master

Reviewers

Index handling for SQLite was a bit of a mess. When a table is rebuilt,
the old table gets dropped, losing any indexes. The official
instructions state that these should be rebuilt, but this wasn't always
happening. Some changes would prompt a rebuild, but not all.

We now unconditionally rebuild indexes after a rebuild. Note that we do
not preserve any non-default indexes (so if a user has set up a custom
index, it will likely be lost), but this isn't a new problem.

To make this happen, a bad default operation in the common code had to
be removed. We were always attempting to create an index if adding a
field that required one, which is fine for most databases, but it meant
that the SQLite code then had to work around this logic. That's part of
why other operations didn't end up creating indexes reliably.

There was also a pretty brute-force operation that could be performed,
which was dropping a unique_together constraint. This was being done by
simply performing a table rebuild, which surely dropped that index, but
also dropped all the other ones. Older versions of Django needed this
due to utilizing SQLite-created auto-indexes, which could not be dropped
without a table rebuild, but it's not necessary on modern versions.

These auto-indexes are still handled through a full table rebuild, but
all others are now dropped normally, removing any side-effects on a
modern setup.

Unit tests pass for all database on Django 1.6 through 2.0. Tested with
Python 2.7 and 3.8.

Summary ID
Fix restoring table indexes when rebuilding a table on SQLite.
Index handling for SQLite was a bit of a mess. When a table is rebuilt, the old table gets dropped, losing any indexes. The official instructions state that these should be rebuilt, but this wasn't always happening. Some changes would prompt a rebuild, but not all. We now unconditionally rebuild indexes after a rebuild. Note that we do *not* preserve any non-default indexes (so if a user has set up a custom index, it will likely be lost), but this isn't a new problem. To make this happen, a bad default operation in the common code had to be removed. We were always attempting to create an index if adding a field that required one, which is fine for most databases, but it meant that the SQLite code then had to work around this logic. That's part of why other operations didn't end up creating indexes reliably. There was also a pretty brute-force operation that could be performed, which was dropping a unique_together constraint. This was being done by simply performing a table rebuild, which surely dropped that index, but also dropped all the other ones. Older versions of Django needed this due to utilizing SQLite-created auto-indexes, which could not be dropped without a table rebuild, but it's not necessary on modern versions. These auto-indexes are still handled through a full table rebuild, but all others are now dropped normally, removing any side-effects on a modern setup.
b8909362962e800b78f44ed69a0727ff68849d54
Description From Last Updated

F401 'django' imported but unused

reviewbotreviewbot
Checks run (1 failed, 1 succeeded)
flake8 failed.
JSHint passed.

flake8

david
  1. Ship It!
  2. 
      
chipx86
Review request changed
Status:
Completed
Change Summary:
Pushed to master (44327a5)