Skip to content

Comments

fix(sqlite): ignore choices-only alters (swev-id: django__django-15561)#502

Open
casey-brooks wants to merge 1 commit intodjango__django-15561from
fix/sqlite-choices-alter-noop-django__django-15561
Open

fix(sqlite): ignore choices-only alters (swev-id: django__django-15561)#502
casey-brooks wants to merge 1 commit intodjango__django-15561from
fix/sqlite-choices-alter-noop-django__django-15561

Conversation

@casey-brooks
Copy link

@casey-brooks casey-brooks commented Dec 24, 2025

Problem

  • Altering a CharField on SQLite that only changes choices currently triggers a table rebuild.
  • These unnecessary rebuilds slow migrations and risk lock contention even though the schema is unchanged.

Fix

  • Override _field_should_be_altered() in the SQLite schema editor to treat choices as a non-database attribute so choices-only updates are skipped.
  • Add a regression test verifying alter_field() collects no SQL for a choices-only update.

Issue

Observed failure (pre-fix)

AssertionError: Lists differ: ['CREATE TABLE "new__backends_author" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(255) NOT NULL UNIQUE);', 'INSERT INTO "new__backends_author" ("id", "name") SELECT "id", "name" FROM "backends_author";', 'DROP TABLE "backends_author";', 'ALTER TABLE "new__backends_author" RENAME TO "backends_author";'] != []

CREATE TABLE "new__backends_author" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(255) NOT NULL UNIQUE);
INSERT INTO "new__backends_author" ("id", "name") SELECT "id", "name" FROM "backends_author";
DROP TABLE "backends_author";
ALTER TABLE "new__backends_author" RENAME TO "backends_author";

Traceback (pre-fix)

Traceback (most recent call last):
  File "django/tests/backends/sqlite/tests.py", line 214, in test_alter_field_choices_noop
    self.assertEqual(editor.collected_sql, [])
AssertionError: Lists differ: [...SQL statements...] != []

Reproduction

  • ./runtests.py backends.sqlite -k test_alter_field_choices_noop
  • python -m pytest -q django/tests/backends/sqlite/tests.py::SchemaTests::test_alter_field_choices_noop

Reference: internal task swev-id: django__django-15561.

@casey-brooks casey-brooks requested a review from a team December 24, 2025 16:35
@casey-brooks
Copy link
Author

Local Validation

  • PYTHONPATH=/workspace/django:$HOME/.nix-profile/lib/python3.11/site-packages DJANGO_SETTINGS_MODULE=tests.test_sqlite python3 tests/runtests.py backends.sqlite -k test_alter_field_choices_noop → 1 passed / 0 failed / 0 skipped
  • PYTHONPATH=/workspace/django:$HOME/.nix-profile/lib/python3.11/site-packages flake8 django/db/backends/sqlite3/schema.py tests/backends/sqlite/tests.py → no lint errors

Copy link

@noa-lucent noa-lucent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Thanks for scoping the change to SQLite and adding the regression test.

@rowan-stein rowan-stein changed the base branch from django__django-15561 to main January 11, 2026 20:30
@rowan-stein rowan-stein changed the base branch from main to django__django-15561 January 12, 2026 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SQLite: AlterField should be no-op for choices-only changes

2 participants