Opened 6 years ago

Last modified 3 years ago

#29854 closed Bug

Altering model primary key might cause referred foreign key attribution inconsistent — at Version 3

Reported by: Rick Yang Owned by: nobody
Component: Migrations Version: dev
Severity: Normal Keywords: MySQL, Migration, Altering primary key,
Cc: Collin Anderson Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Rick Yang)

Django 1.11.8~16 can reproduce this issue.
DB is MySQL

Reproduced Steps:

  1. Create models as following:
class TestModel(models.Model):
    filing_no = models.CharField(max_length=16, primary_key=True)


class OtherModel1(models.Model):
    id = models.AutoField(primary_key=True)

    # null=True
    f = models.ForeignKey(TestModel, null=True)


class OtherModel2(models.Model):
    id = models.AutoField(primary_key=True)
    f = models.ForeignKey(TestModel)


class OtherModel3(models.Model):
    id = models.AutoField(primary_key=True)
    f = models.ForeignKey(TestModel)


class OtherModel4(models.Model):
    id = models.AutoField(primary_key=True)
    f = models.ForeignKey(TestModel)


class OtherModel5(models.Model):
    id = models.AutoField(primary_key=True)
    f = models.ForeignKey(TestModel)


class OtherModel6(models.Model):
    id = models.AutoField(primary_key=True)
    f = models.ForeignKey(TestModel)


class OtherModel7(models.Model):
    id = models.AutoField(primary_key=True)
    f = models.ForeignKey(TestModel)


class OtherModel8(models.Model):
    id = models.AutoField(primary_key=True)
    f = models.ForeignKey(TestModel)


class OtherModel9(models.Model):
    id = models.AutoField(primary_key=True)
    f = models.ForeignKey(TestModel)


class OtherModel10(models.Model):
    id = models.AutoField(primary_key=True)
    f = models.ForeignKey(TestModel)
  1. Based on above models, we change max_length of TestModel's filing_no and auto-generate migration code as following, and then perform migrating.
        migrations.AlterField(
            model_name='testmodel',
            name='filing_no',
            field=models.CharField(max_length=24, primary_key=True, serialize=False),
        ),
  1. Check DB schema of table OtherModel1~10, field f's nullable attribution becomes False, and field f's nullable attribution in some other OtherModel becomes True.

My investigation:

In function BaseDatabaseSchemaEditor._alter_field(), the function call _related_non_m2m_objects(old_field, new_field) will return inconsistent "old" and "new" related_objects pairs (the model order is different), and generate wrong SQL command to alter foreign keys.

Change History (3)

comment:1 by Rick Yang, 6 years ago

Type: UncategorizedBug

comment:2 by Rick Yang, 6 years ago

Description: modified (diff)

comment:3 by Rick Yang, 6 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top