Opened 9 years ago

Closed 8 years ago

#26088 closed Bug (fixed)

Changing a proxy model to multi-table inheritance does not modify FKs of the model

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

Description

Original models.py:

class MyBaseModel(models.Model):
    pass

class MyModel(MyBaseModel):
    class Meta:
        proxy = True

class MyOtherModel(models.Model):
    my_model = models.ForeignKey(MyModel)

The initial migration creates the expected FK (full migration 0001_initial.py below): "myapp_myothermodel_my_model_id_cce558da_fk_myapp_mybasemodel_id" FOREIGN KEY (my_model_id) REFERENCES myapp_mybasemodel(id) DEFERRABLE INITIALLY DEFERRED.

Later, I may decide to use multi-table inheritance. To do so, I would remove the proxy = True from MyModel. After running makemigrations, the new migration creates the new table, but does not adjust the existing FK. (full migration 0002_auto.py below.)

If I had used multi-table inheritance from the start, the initial migration would have created the correct FK as expected. The end results is that these identically defined models have different database schema.

The fact that this FK is pointing to the incorrect table and field could potentially break data integrity checks and expectations as the FK is not verified against the correct model/table.

0001_initial.py

# -*- coding: utf-8 -*-
# Generated by Django 1.10.dev20160115013918 on 2016-01-15 01:39
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='MyBaseModel',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ],
        ),
        migrations.CreateModel(
            name='MyOtherModel',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ],
        ),
        migrations.CreateModel(
            name='MyModel',
            fields=[
            ],
            options={
                'proxy': True,
            },
            bases=('myapp.mybasemodel',),
        ),
        migrations.AddField(
            model_name='myothermodel',
            name='my_model',
            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='myapp.MyModel'),
        ),
    ]

0002_auto.py

# -*- coding: utf-8 -*-
# Generated by Django 1.10.dev20160115014052 on 2016-01-15 01:41
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0001_initial'),
    ]

    operations = [
        migrations.DeleteModel(
            name='MyModel',
        ),
        migrations.CreateModel(
            name='MyModel',
            fields=[
                ('mybasemodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='myapp.MyBaseModel')),
            ],
            bases=('myapp.mybasemodel',),
        ),
    ]

(All tests ran using master branch of Django with PostgreSQL backend.)

Change History (3)

comment:1 by Tim Graham, 9 years ago

Summary: makemigrations: Changing a proxy model to multi--table inheritance does not modify FKs of the modelChanging a proxy model to multi-table inheritance does not modify FKs of the model
Triage Stage: UnreviewedAccepted

comment:3 by Tim Graham <timograham@…>, 8 years ago

Resolution: fixed
Status: newclosed

In b84ecaa7:

Fixed #26088 -- Made autodector detect changing proxy model to MTI.

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