﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
23956	makemigrations creates broken initial migration for models with multiple inheritance	Kirill Gagarski	nobody	"Hello.
I am trying to create models that use multiple inheritance and then use django migrations mechanism to migrate. But I have some problems with it.

I have created simplest example to reproduce.

 = Steps to reproduce = 

1. Create a `migrationstest` django app with following `models.py`:

{{{
from django.db import models


class A(models.Model):
    a_id = models.AutoField(primary_key=True)


class B(models.Model):
    b_id = models.AutoField(primary_key=True)


class C(A, B):
    pass


class D(A, B):
    pass


class E(A, B):
    pass

}}}
2. run './manage.py makemigrations migrationstest'
3. run './manage.py migrate migrationstest'

 = Expected results = 

Fine migration

 = Actual results = 
Exception is thrown while running 'migrate':
{{{
Traceback (most recent call last):
  File ""./manage.py"", line 10, in <module>
    execute_from_command_line(sys.argv)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/core/management/__init__.py"", line 385, in execute_from_command_line
    utility.execute()
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/core/management/__init__.py"", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/core/management/base.py"", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/core/management/base.py"", line 338, in execute
    output = self.handle(*args, **options)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/core/management/commands/migrate.py"", line 160, in handle
    executor.migrate(targets, plan, fake=options.get(""fake"", False))
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/db/migrations/executor.py"", line 63, in migrate
    self.apply_migration(migration, fake=fake)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/db/migrations/executor.py"", line 97, in apply_migration
    migration.apply(project_state, schema_editor)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/db/migrations/migration.py"", line 107, in apply
    operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/db/migrations/operations/fields.py"", line 37, in database_forwards
    field,
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/db/backends/schema.py"", line 390, in add_field
    self.execute(sql, params)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/db/backends/schema.py"", line 99, in execute
    cursor.execute(sql, params)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/db/backends/utils.py"", line 81, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/db/backends/utils.py"", line 65, in execute
    return self.cursor.execute(sql, params)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/db/utils.py"", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/utils/six.py"", line 549, in reraise
    raise value.with_traceback(tb)
  File ""/home/gagarski/polyana-web/environment/lib/python3.4/site-packages/django/db/backends/utils.py"", line 65, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: column ""b_ptr_id"" of relation ""migrationstest_d"" already exists
}}}

 = More details = 

The generated initial migration:
{{{
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='A',
            fields=[
                ('a_id', models.IntegerField(serialize=False, primary_key=True)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='B',
            fields=[
                ('b_id', models.IntegerField(serialize=False, primary_key=True)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='C',
            fields=[
                ('a_ptr', models.OneToOneField(parent_link=True, serialize=False, primary_key=True, to='migrationstest.A', auto_created=True)),
            ],
            options={
            },
            bases=('migrationstest.a', 'migrationstest.b'),
        ),
        migrations.CreateModel(
            name='D',
            fields=[
                ('a_ptr', models.OneToOneField(parent_link=True, serialize=False, primary_key=True, to='migrationstest.A', auto_created=True)),
            ],
            options={
            },
            bases=('migrationstest.a', 'migrationstest.b'),
        ),
        migrations.CreateModel(
            name='E',
            fields=[
                ('a_ptr', models.OneToOneField(parent_link=True, serialize=False, primary_key=True, to='migrationstest.A', auto_created=True)),
                ('b_ptr', models.OneToOneField(parent_link=True, to='migrationstest.B', auto_created=True)),
            ],
            options={
            },
            bases=('migrationstest.a', 'migrationstest.b'),
        ),
        migrations.AddField(
            model_name='d',
            name='b_ptr',
            field=models.OneToOneField(parent_link=True, to='migrationstest.B', auto_created=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='c',
            name='b_ptr',
            field=models.OneToOneField(parent_link=True, to='migrationstest.B', auto_created=True),
            preserve_default=True,
        ),
    ]
}}}

As you can see `b_ptr` field is added in `CreateModel `only for the last model (`E`).
For `D` and `C` it is added via `AddField`. But it seems that `b_ptr` is already added to them even without a field specified in `CreateModel`'s `fields` argument (with the help of `bases` argument, I think).

 == Output of `sqlmigrate` ==
{{{
BEGIN;
CREATE TABLE ""migrationstest_a"" (""a_id"" integer NOT NULL PRIMARY KEY);
CREATE TABLE ""migrationstest_b"" (""b_id"" integer NOT NULL PRIMARY KEY);
CREATE TABLE ""migrationstest_c"" (""b_ptr_id"" integer NOT NULL UNIQUE, ""a_ptr_id"" integer NOT NULL PRIMARY KEY);
CREATE TABLE ""migrationstest_d"" (""b_ptr_id"" integer NOT NULL UNIQUE, ""a_ptr_id"" integer NOT NULL PRIMARY KEY);
CREATE TABLE ""migrationstest_e"" (""b_ptr_id"" integer NOT NULL UNIQUE, ""a_ptr_id"" integer NOT NULL PRIMARY KEY);
ALTER TABLE ""migrationstest_d"" ADD COLUMN ""b_ptr_id"" integer NOT NULL UNIQUE;
ALTER TABLE ""migrationstest_d"" ALTER COLUMN ""b_ptr_id"" DROP DEFAULT;
ALTER TABLE ""migrationstest_c"" ADD COLUMN ""b_ptr_id"" integer NOT NULL UNIQUE;
ALTER TABLE ""migrationstest_c"" ALTER COLUMN ""b_ptr_id"" DROP DEFAULT;
ALTER TABLE ""migrationstest_c"" ADD CONSTRAINT ""migrationste_b_ptr_id_6684147e60c05d18_fk_migrationstest_b_b_id"" FOREIGN KEY (""b_ptr_id"") REFERENCES ""migrationstest_b"" (""b_id"") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE ""migrationstest_c"" ADD CONSTRAINT ""migrationste_a_ptr_id_2670758b3e821055_fk_migrationstest_a_a_id"" FOREIGN KEY (""a_ptr_id"") REFERENCES ""migrationstest_a"" (""a_id"") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE ""migrationstest_d"" ADD CONSTRAINT ""migrationste_b_ptr_id_2ed6e3025678dfb9_fk_migrationstest_b_b_id"" FOREIGN KEY (""b_ptr_id"") REFERENCES ""migrationstest_b"" (""b_id"") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE ""migrationstest_d"" ADD CONSTRAINT ""migrationste_a_ptr_id_4d0009d1fad71dec_fk_migrationstest_a_a_id"" FOREIGN KEY (""a_ptr_id"") REFERENCES ""migrationstest_a"" (""a_id"") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE ""migrationstest_e"" ADD CONSTRAINT ""migrationste_b_ptr_id_29d2159648c59c3e_fk_migrationstest_b_b_id"" FOREIGN KEY (""b_ptr_id"") REFERENCES ""migrationstest_b"" (""b_id"") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE ""migrationstest_e"" ADD CONSTRAINT ""migrationste_a_ptr_id_405a8eb9707708c9_fk_migrationstest_a_a_id"" FOREIGN KEY (""a_ptr_id"") REFERENCES ""migrationstest_a"" (""a_id"") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE ""migrationstest_d"" ADD CONSTRAINT ""migrationste_b_ptr_id_2ed6e3025678dfb9_fk_migrationstest_b_b_id"" FOREIGN KEY (""b_ptr_id"") REFERENCES ""migrationstest_b"" (""b_id"") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE ""migrationstest_c"" ADD CONSTRAINT ""migrationste_b_ptr_id_6684147e60c05d18_fk_migrationstest_b_b_id"" FOREIGN KEY (""b_ptr_id"") REFERENCES ""migrationstest_b"" (""b_id"") DEFERRABLE INITIALLY DEFERRED;

COMMIT;

}}}

 = Questions =
Is there a good reasons to do like that? Is there a workaround that can help me to use automatic migration generation without manually editing them (at least initial migration)?"	Bug	new	Migrations	1.7	Normal		migrations inheritance		Unreviewed	0	0	0	0	0	0
