• 
      

    Fix ChangeField failure with index+column type changes on MySQL.

    Review Request #14922 — Created March 17, 2026 and updated

    Information

    Django Evolution
    master

    Reviewers

    When a ChangeField mutation changes both the field type and
    unique/db_index attributes, MySQL's MODIFY COLUMN runs before the
    index is dropped. MySQL rejects this for TEXT or BLOB columns with
    the error "BLOB/TEXT column used in key specification without a key
    length".

    This happened because ChangeField.mutate() returns early after
    change_column_type() when change_column_type_sets_attrs is True
    (MySQL), skipping the change_column_attrs() call that handles index
    drops.

    change_column_type() now processes db_index/unique changes from
    new_attrs when change_column_type_sets_attrs is True, emitting
    index drops as pre-SQL (before the MODIFY) and index adds as post-SQL
    (after). The SQLite3 backend also calls the new helper to keep in-memory
    database state in sync.

    • Ran unit tests without the fix and verified that the new tests failed with
      the same issue I saw in the wild.
    • Ran unit tests with the fix and verified that it was now fixed.
    • Ran dbtests for mysql, sqlite, and postgresql.
    Summary ID
    Fix ChangeField failure with index+column type changes on MySQL.
    When a `ChangeField` mutation changes both the field type and `unique`/`db_index` attributes, MySQL's `MODIFY COLUMN` runs before the index is dropped. MySQL rejects this for `TEXT` or `BLOB` columns with the error "BLOB/TEXT column used in key specification without a key length". This happened because `ChangeField.mutate()` returns early after `change_column_type()` when `change_column_type_sets_attrs` is `True` (MySQL), skipping the `change_column_attrs()` call that handles index drops. `change_column_type()` now processes `db_index`/`unique` changes from `new_attrs` when `change_column_type_sets_attrs` is `True`, emitting index drops as pre-SQL (before the `MODIFY`) and index adds as post-SQL (after). The SQLite3 backend also calls the new helper to keep in-memory database state in sync. Testing Done: - Ran unit tests without the fix and verified that the new tests failed with the same issue I saw in the wild. - Ran unit tests with the fix and verified that it was now fixed. - Ran dbtests for mysql, sqlite, and postgresql.
    qnonyqrrwwqqowzwqpqlwpvvslzxpvum
    Description From Last Updated

    continuation line over-indented for visual indent Column: 48 Error code: E127

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

    flake8

    david
    Review request changed
    Commits:
    Summary ID
    Fix ChangeField failure with index+column type changes on MySQL.
    When a `ChangeField` mutation changes both the field type and `unique`/`db_index` attributes, MySQL's `MODIFY COLUMN` runs before the index is dropped. MySQL rejects this for `TEXT` or `BLOB` columns with the error "BLOB/TEXT column used in key specification without a key length". This happened because `ChangeField.mutate()` returns early after `change_column_type()` when `change_column_type_sets_attrs` is `True` (MySQL), skipping the `change_column_attrs()` call that handles index drops. `change_column_type()` now processes `db_index`/`unique` changes from `new_attrs` when `change_column_type_sets_attrs` is `True`, emitting index drops as pre-SQL (before the `MODIFY`) and index adds as post-SQL (after). The SQLite3 backend also calls the new helper to keep in-memory database state in sync. Testing Done: - Ran unit tests without the fix and verified that the new tests failed with the same issue I saw in the wild. - Ran unit tests with the fix and verified that it was now fixed. - Ran dbtests for mysql, sqlite, and postgresql.
    qnonyqrrwwqqowzwqpqlwpvvslzxpvum
    Fix ChangeField failure with index+column type changes on MySQL.
    When a `ChangeField` mutation changes both the field type and `unique`/`db_index` attributes, MySQL's `MODIFY COLUMN` runs before the index is dropped. MySQL rejects this for `TEXT` or `BLOB` columns with the error "BLOB/TEXT column used in key specification without a key length". This happened because `ChangeField.mutate()` returns early after `change_column_type()` when `change_column_type_sets_attrs` is `True` (MySQL), skipping the `change_column_attrs()` call that handles index drops. `change_column_type()` now processes `db_index`/`unique` changes from `new_attrs` when `change_column_type_sets_attrs` is `True`, emitting index drops as pre-SQL (before the `MODIFY`) and index adds as post-SQL (after). The SQLite3 backend also calls the new helper to keep in-memory database state in sync. Testing Done: - Ran unit tests without the fix and verified that the new tests failed with the same issue I saw in the wild. - Ran unit tests with the fix and verified that it was now fixed. - Ran dbtests for mysql, sqlite, and postgresql.
    qnonyqrrwwqqowzwqpqlwpvvslzxpvum

    Checks run (2 succeeded)

    flake8 passed.
    JSHint passed.