From b34238addceb6b2d40181b625da3b7b7104abfcd Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Fri, 29 Apr 2022 20:16:34 +0200 Subject: [PATCH] Fixed #33670 -- Fixed altering primary key on SQLite. --- django/db/backends/sqlite3/schema.py | 7 ++++++- tests/schema/tests.py | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py index b3a2f4282b..21e1b35fce 100644 --- a/django/db/backends/sqlite3/schema.py +++ b/django/db/backends/sqlite3/schema.py @@ -217,7 +217,12 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): alter_field and getattr(alter_field[1], "primary_key", False) ): for name, field in list(body.items()): - if field.primary_key: + if field.primary_key and not ( + # Do not remove the old primary key when an altered field + # that introduces a primary key is the same field. + alter_field + and name == alter_field[1].name + ): field.primary_key = False restore_pk_field = field if field.auto_created: diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 049e604480..3fe41f5336 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -3584,6 +3584,21 @@ class SchemaTests(TransactionTestCase): ) self.assertEqual(self.get_primary_key(Tag._meta.db_table), "slug") + def test_alter_primary_key_the_same_name(self): + with connection.schema_editor() as editor: + editor.create_model(Thing) + + old_field = Thing._meta.get_field("when") + new_field = CharField(max_length=2, primary_key=True) + new_field.set_attributes_from_name("when") + new_field.model = Thing + with connection.schema_editor() as editor: + editor.alter_field(Thing, old_field, new_field, strict=True) + self.assertEqual(self.get_primary_key(Thing._meta.db_table), "when") + with connection.schema_editor() as editor: + editor.alter_field(Thing, new_field, old_field, strict=True) + self.assertEqual(self.get_primary_key(Thing._meta.db_table), "when") + def test_context_manager_exit(self): """ Ensures transaction is correctly closed when an error occurs