Repository navigation
fix(migrations): create index for fields added with db_index=True - #2384
Open
nk-batman21 wants to merge 1 commit into
Open
nk-batman21 wants to merge 1 commit into
nk-batman21 wants to merge 1 commit into
Conversation
AddField only emitted ALTER TABLE ... ADD COLUMN, so a field added to an existing model with db_index=True never got its index, while CreateModel and AlterField both create it. add_field now calls add_index after adding the column, as _alter_field does. A plain single-column index on a db_index field has the same name as the field's own index, so AddIndex and RemoveIndex now skip it, the way CreateModel already merges the two. Existing migrations that pair such an AddField with an AddIndex on the same column keep applying on a fresh database. The generated-field recreate path no longer emits its own AddIndex for the field, since AddField now creates that index.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
AddFieldonly runsALTER TABLE ... ADD COLUMN, so a field added to an existing model withdb_index=Truenever gets its index.CreateModelandAlterFieldboth create it.To hit it, add
email = fields.CharField(max_length=200, null=True, db_index=True)to an existingUsermodel and runmakemigrationsandmigrate.sqlmigrateshows onlyALTER TABLE "user" ADD COLUMN "email" VARCHAR(200);, the table has no index afterwards, and the nextmakemigrationsreports no changes because the migration state already hasdb_index=True.add_fieldin the base and SQLite schema editors now callsadd_indexafter adding the column, as_alter_fielddoes. The index gets the sameidx_...name as inCreateModel, so a laterAlterFieldtodb_index=Falsedrops it. For aForeignKeyFieldthe index goes on its column (e.g.writer_id).Some existing migrations also add an unnamed single-column
Indexon such a column: from listing it inMeta.indexesas a workaround, or theAddIndexthe autodetector used to emit when recreating a generated field (no longer emitted). That index has the same name, soAddIndexandRemoveIndexnow skip it, also on downgrade, the wayCreateModelalready merges the two. Without this those migrations would fail on a fresh database withindex ... already exists. Named, typed, partial and multi-column indexes are unchanged. Two limits: a database that applied theAddFieldbefore this change keeps missing the index, and on MSSQL rolling back such anAddFieldnow hits the existingDROP COLUMNlimit for indexed columns, as withCreateModel.Motivation and Context
Adding an indexed column to an existing table is a routine change. Today the migration applies cleanly and the index is silently missing, on every backend.
How Has This Been Tested?
New tests for the base editor (plain field and
ForeignKeyFieldwithsource_field), the SQLite editor, andAddFieldfollowed byAddIndex/RemoveIndexon the same column. The generated-field recreate test now expects only the GINAddIndex. All four fail without the change.Ran:
pytest tests/migrationsand the SQLite test suiteRan: the CLI steps above on SQLite, plus
db_index=Truetogether withMeta.indexes = [("email",)]in the same migration and in a later one: one index each time, downgrades and removing theMeta.indexesentry workRan: the comprehensive migrations example (
migrate,downgrade erp)Checked:
ruff format --check,ruff check,mypyChecklist: