#34665 closed Bug (invalid)

CreateModel with manually added RenameField crashes on SQLite.

Reported by: Amchii Owned by: nobody
Component: Database layer (models, ORM) Version: 4.2
Severity: Normal Keywords: sqlite3
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using the SQLite database to perform migrations in Django 4.1 and 4.2, an OperationalError is thrown; however, it works normally on versions below 4.1 and also works normally on MySQL.

Here's the reproduction steps(use sqlite3):

  1. models.py:
    from django.db import models
    
    
    class Person(models.Model):
        class Meta:
            db_table = "person"
    
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        open_id = models.PositiveBigIntegerField(db_index=True)
    
  1. run python manage.py makemigrations and it generates

0001_initial.py:

# Generated by Django 4.2.2 on 2023-06-19 06:10

from django.db import migrations, models


class Migration(migrations.Migration):
    initial = True

    dependencies = []

    operations = [
        migrations.CreateModel(
            name="Person",
            fields=[
                (
                    "id",
                    models.BigAutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                ("name", models.CharField(max_length=32)),
                ("age", models.IntegerField()),
                ("open_id", models.PositiveBigIntegerField(db_index=True)),
            ],
            options={
                "db_table": "person",
            },
        ),
    ]
  1. rename field open_id -> open_uid, edit 0001_initial.py and add this line:
migrations.RenameField(
            model_name="person",
            old_name="open_id",
            new_name="open_uid",
        ),
  1. remove field 'age' and run python manage.py makemigrations, it generates 0002_remove_person_age.py:
# Generated by Django 4.2.2 on 2023-06-19 06:12

from django.db import migrations


class Migration(migrations.Migration):
    dependencies = [
        ("myapp", "0001_initial"),
    ]

    operations = [
        migrations.RemoveField(
            model_name="person",
            name="age",
        ),
    ]

  1. run python manage.py migrate, it raises:

django.db.utils.OperationalError: error in index person_open_id_aac92076 after drop column: no such column: open_id

I encountered this issue while testing after upgrading an old project from Django version to 4.1. Although I manually added a line instead of using makemigrations when renaming the 'open_id' field, it should still work properly?

Change History (1)

comment:1 by Mariusz Felisiak, 17 months ago

Resolution: invalid
Status: newclosed
Summary: An OperationalError is thrown when using SQLite database in Django 4.1 during 'migrate', while it works normally on versions below 4.1 and also works normally on MySQL.CreateModel with manually added RenameField crashes on SQLite.

It worked on Django 4.0 because the person table was recreated by the second migrations (which is no longer necessary in SQLite 3.35.5+, see 3702819227fd0cdd9b581cd99e11d1561d51cbeb), however in all versions of Django index is created on a wrong column:

ALTER TABLE "person" RENAME COLUMN "open_id" TO "open_uid";
CREATE INDEX "person_open_id_aac92076" ON "person" ("open_id");

Although I manually added a line instead of using makemigrations when renaming the 'open_id' field, it should still work properly?

In general, you can edit migrations manually, but you do so at your own risk. In this case you should update the column name in the CreateModel operation instead of adding RenameField.

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