#28438: Initial migration creates fields not listed in the migration if mixin class changes -----------------------------------------+------------------------ Reporter: Michal Dabski | Owner: nobody Type: Uncategorized | Status: new Component: Uncategorized | Version: 1.11 Severity: Normal | Keywords: Triage Stage: Unreviewed | Has patch: 0 Needs documentation: 0 | Needs tests: 0 Patch needs improvement: 0 | Easy pickings: 0 UI/UX: 0 | -----------------------------------------+------------------------ Consider the sample model with a mixin class: {{{ from django.db import models
class TestMixin(object): pass class TestModel(TestMixin, models.Model): sample_field = models.CharField(max_length=20) }}} When running makemigrations, django creates a perfectly good and valid migration: {{{ # -*- coding: utf-8 -*- # Generated by Django 1.11.3 on 2017-07-26 17:03 from __future__ import unicode_literals from django.db import migrations, models import migration_test.models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='TestModel', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('sample_field', models.CharField(max_length=20)), ], bases=(migration_test.models.TestMixin, models.Model), ), ] }}} SQL: {{{ BEGIN; -- -- Create model TestModel -- CREATE TABLE "migration_test_testmodel" ("id" serial NOT NULL PRIMARY KEY, "sample_field" varchar(20) NOT NULL); COMMIT; }}} Next, refactor mixin class to add a field to it - need to change mixin's base class to {{{models.Model}}}, otherwise field will not be correctly inherited by models: {{{ class TestMixin(models.Model): mixin_field = models.CharField(max_length=20, default='test') class Meta: abstract = True }}} Thie creates a new migration which adds {{{mixin_field}}} to it - nothing special. However, when applying both migrations after the model changes, second migration fails with the following error {{{django.db.utils.ProgrammingError: column "mixin_field" of relation "migration_test_testmodel" already exists}}}. as it turns out, the first migration's SQL has now changed to include {{{mixin_field}}}: {{{ BEGIN; -- -- Create model TestModel -- CREATE TABLE "migration_test_testmodel" ("id" serial NOT NULL PRIMARY KEY, "mixin_field" varchar(20) NOT NULL, "sample_field" varchar(20) NOT NULL); COMMIT; }}} The python code of the migration obviously has not changed, but the resulting SQL did, and it includes a field not explicitly listed in the migration's {{{fields}}}. Note: - this does not happen if the mixin class extends {{{models.Model}}} to begin with. - if model extends a mixin that extends {{{object}}}, it ends up in model's {{{bases}}}, however if mixin extends {{{model.Model}}} it does not. Tested with Django 1.11.3, Python 2.7 -- Ticket URL: <https://code.djangoproject.com/ticket/28438> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/049.52ccadcb941c033f0bccb2404f914012%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.