Opened 3 months ago

Closed 3 months ago

#35635 closed Bug (needsinfo)

Adding a field with a default in migrations following an index rename seems to fail

Reported by: Raphael Gaschignard Owned by:
Component: Migrations Version: 5.0
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Raphael Gaschignard)

I have the following migration:

    operations = [
        migrations.RenameIndex(
            model_name="taggeditem",
            new_name="taggit_tagg_content_8fc721_idx",
            old_fields=("content_type", "object_id"),
        ),
    ]

I have created another migration after this one:

    dependencies = [
        (
            "taggit",
            "0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx",
        ),
    ]

    operations = [
        migrations.AddField(
            model_name="taggeditem",
            name="created_at",
            field=models.DateTimeField(
                blank=True, default=django.utils.timezone.now, null=True
            ),
        ),
    ]

This gives the following for sqlmigrate:

BEGIN;
--
-- Add field created_at to taggeditem
--
CREATE TABLE "new__taggit_taggeditem" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created_at" datetime NULL, "object_id" integer NOT NULL, "content_type_id" integer NOT NULL REFERENCES "django_content_type" ("id") DEFERRABLE INITIALLY DEFERRED, "tag_id" integer NOT NULL REFERENCES "taggit_tag" ("id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "taggit_taggeditem_content_type_id_object_id_tag_id_4bb97a8e_uniq" UNIQUE ("content_type_id", "object_id", "tag_id"));
INSERT INTO "new__taggit_taggeditem" ("id", "object_id", "content_type_id", "tag_id", "created_at") SELECT "id", "object_id", "content_type_id", "tag_id", '2024-07-27 00:31:47.134946' FROM "taggit_taggeditem";
DROP TABLE "taggit_taggeditem";
ALTER TABLE "new__taggit_taggeditem" RENAME TO "taggit_taggeditem";
CREATE INDEX "taggit_taggeditem_object_id_e2d7d1df" ON "taggit_taggeditem" ("object_id");
CREATE INDEX "taggit_taggeditem_content_type_id_9957a03c" ON "taggit_taggeditem" ("content_type_id");
CREATE INDEX "taggit_taggeditem_tag_id_f4f5b767" ON "taggit_taggeditem" ("tag_id");
CREATE INDEX "taggit_tagg_content_8fc721_idx" ON "taggit_taggeditem" ("content_type_id", "object_id");
CREATE INDEX "taggit_tagg_content_8fc721_idx" ON "taggit_taggeditem" ("content_type_id", "object_id");
COMMIT;

Note in particular the creating of two indexes with the same name.

Now, if I don't set a default in the AddField operation , the sqlmigrate result is simply as follows:

BEGIN;
--
-- Add field created_at to taggeditem
--
ALTER TABLE "taggit_taggeditem" ADD COLUMN "created_at" datetime NULL;
COMMIT;

And if I comment out the RenameIndex operation, I only create the index once, not twice, avoiding the issue.

Extra detail: I hit this because I have an index with a name, and then a RenameIndex operation that renames it.
It seems like we would expect there to be a cleanup operation during a rename. Instead, it creates the migration twice.

I have only tested this out with the SQLite driver, and I have a suspicion it's only happening there, because... well... this seems like something that would break elsewhere.

Reproduced this with 5.1rc1 and 5.0.6

Reproduction:

Change History (2)

comment:1 by Raphael Gaschignard, 3 months ago

Description: modified (diff)

comment:2 by David Sanders, 3 months ago

Resolution: needsinfo
Status: newclosed

Hi & thanks for the report.

Although I observed the exception on the branch you've linked, I couldn't reproduce this with a simple example following the steps provided.

My advice would be to reproduce this either with the simplest setup possible or through a unit test then paste the details here 👍

Closing with needsinfo for now until more info or someone with more time can investigate and confirm the presence of a bug with Django,

Note: See TracTickets for help on using tickets.
Back to Top