Skip to content

Commit

Permalink
Fixed #28541 -- Fixed migrations crash when changing primary key on S…
Browse files Browse the repository at this point in the history
…QLite.
  • Loading branch information
bcail authored and felixxm committed Mar 14, 2024
1 parent 3d7235c commit 593067a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
8 changes: 8 additions & 0 deletions django/db/backends/sqlite3/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ def is_self_referential(f):
body_copy["__module__"] = model.__module__
new_model = type("New%s" % model._meta.object_name, model.__bases__, body_copy)

# Remove the automatically recreated default primary key, if it has
# been deleted.
if delete_field and delete_field.attname == new_model._meta.pk.attname:
auto_pk = new_model._meta.pk
delattr(new_model, auto_pk.attname)
new_model._meta.local_fields.remove(auto_pk)
new_model.pk = None

# Create a new table with the updated schema.
self.create_model(new_model)

Expand Down
36 changes: 36 additions & 0 deletions tests/migrations/test_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2802,6 +2802,42 @@ def assertIdTypeEqualsMTIFkType():
(f"{app_label}_pony", "id"),
)

def test_alter_id_pk_to_uuid_pk(self):
app_label = "test_alidpktuuidpk"
project_state = self.set_up_test_model(app_label)
new_state = project_state.clone()
# Add UUID field.
operation = migrations.AddField("Pony", "uuid", models.UUIDField())
operation.state_forwards(app_label, new_state)
with connection.schema_editor() as editor:
operation.database_forwards(app_label, editor, project_state, new_state)
# Remove ID.
project_state = new_state
new_state = new_state.clone()
operation = migrations.RemoveField("Pony", "id")
operation.state_forwards(app_label, new_state)
with connection.schema_editor() as editor:
operation.database_forwards(app_label, editor, project_state, new_state)
self.assertColumnNotExists(f"{app_label}_pony", "id")
# Rename to ID.
project_state = new_state
new_state = new_state.clone()
operation = migrations.RenameField("Pony", "uuid", "id")
operation.state_forwards(app_label, new_state)
with connection.schema_editor() as editor:
operation.database_forwards(app_label, editor, project_state, new_state)
self.assertColumnNotExists(f"{app_label}_pony", "uuid")
self.assertColumnExists(f"{app_label}_pony", "id")
# Change to a primary key.
project_state = new_state
new_state = new_state.clone()
operation = migrations.AlterField(
"Pony", "id", models.UUIDField(primary_key=True)
)
operation.state_forwards(app_label, new_state)
with connection.schema_editor() as editor:
operation.database_forwards(app_label, editor, project_state, new_state)

@skipUnlessDBFeature("supports_foreign_keys")
def test_alter_field_reloads_state_on_fk_with_to_field_target_type_change(self):
app_label = "test_alflrsfkwtflttc"
Expand Down

0 comments on commit 593067a

Please sign in to comment.