Opened 7 years ago

Last modified 6 years ago

#27768 closed Cleanup/optimization

makemigrations uses unnecessary AddField for ForeignKey depending on model name — at Initial Version

Reported by: Ed Morley Owned by: nobody
Component: Migrations Version: dev
Severity: Normal Keywords:
Cc: Simon Charette Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Using Django master, for this model makemigrations generates an inefficient migrations file, which uses a combination of CreateModel and AddField, rather than just using a single CreateModel operation.

class Aaa(models.Model):
    pass

class Foo(models.Model):
    fk = models.ForeignKey(Aaa, on_delete=django.db.models.deletion.CASCADE)

Resultant migration operations generated by ./manage.py makemigrations:

    operations = [
        migrations.CreateModel(
            name='Foo',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ],
        ),
        migrations.CreateModel(
            name='Zzz',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ],
        ),
        migrations.AddField(
            model_name='foo',
            name='fk',
            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='testapp.Zzz'),
        ),
    ]

However if the Zzz model was instead called Aaa, then the migration file is correctly optimised (ie: the ForeignKey is defined within the CreateModel operation):

    operations = [
        migrations.CreateModel(
            name='Aaa',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ],
        ),
        migrations.CreateModel(
            name='Foo',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('fk', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='testapp.Aaa')),
            ],
        ),
    ]

Ideally the optimizer would either just use the order as defined in models.py (which would at least allow for users to order them sensibly), or else intelligently sort the models such that those with no (or fewer) foreign keys are listed in operations first, thereby reducing the number of cases where the FK has to be added in a separate AddField operation.

Change History (0)

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