#23581: Changing model field choices results in spurious migrations
-------------------------------+--------------------------------------
     Reporter:  john_scott     |                    Owner:  nobody
         Type:  Uncategorized  |                   Status:  new
    Component:  Migrations     |                  Version:  1.7
     Severity:  Normal         |               Resolution:
     Keywords:                 |             Triage Stage:  Unreviewed
    Has patch:  0              |      Needs documentation:  0
  Needs tests:  0              |  Patch needs improvement:  0
Easy pickings:  0              |                    UI/UX:  0
-------------------------------+--------------------------------------
Changes (by john_scott):

 * needs_better_patch:   => 0
 * needs_tests:   => 0
 * needs_docs:   => 0


Old description:

> Consider a simple model:
>
> {{{#!python
> from django.db import models
>
> CHOICES = (
>     ('1', '1'),
> )
>
> class BasicModel(models.Model):
>     choices = models.CharField(choices=CHOICES, max_length=100)
> }}}
>
> If CHOICES is changed e.g. CHOICES += (('2', '2'),), then
> `makemigrations` insists on creating a new migration for this change.
> However, the migration appears to mostly be a no-op. `sqlmigrate` on
> PostgreSQL shows:
> {{{
> BEGIN;
> ALTER TABLE "core_basicmodel" ALTER COLUMN "choices" DROP DEFAULT;
>
> COMMIT;
> }}}
>
> Which is slightly strange since the initial migration never set a
> DEFAULT, so there is nothing to DROP.
>
> I first noticed this working with django-cms (see
> https://github.com/divio/django-cms/issues/3479). In some cases when I
> attempt to make a migration for an unrelated app, `makemigrations` will
> forcefully create a migration for the `cms` app because the
> settings.CMS_TEMPLATES choices have changed. It then makes this
> automatically created migration a dependency for the migration I actually
> intended to create. There doesn't appear to be a way to avoid this.
>
> This can also happen when the choices differ in development vs
> deployment, Django will complain:
> {{{
>   Your models have changes that are not yet reflected in a migration, and
> so won't be applied.
>   Run 'manage.py makemigrations' to make new migrations, and then re-run
> 'manage.py migrate' to apply them.
> }}}
> So far this seems to mostly be harmless if slightly confusing/annoying. I
> am not familiar with the migration internals, but since 'choices' isn't
> used (at least not on PostgreSQL) to make any actual alterations to the
> database shouldn't it ignore this attribute?

New description:

 Consider a simple model:

 {{{#!python
 from django.db import models

 CHOICES = (
     ('1', '1'),
 )

 class BasicModel(models.Model):
     choices = models.CharField(choices=CHOICES, max_length=100)
 }}}

 If CHOICES is changed e.g. CHOICES += (('2', '2'),), then `makemigrations`
 insists on creating a new migration for this change. However, the
 migration appears to mostly be a no-op. `sqlmigrate` on PostgreSQL shows:
 {{{
 BEGIN;
 ALTER TABLE "core_basicmodel" ALTER COLUMN "choices" DROP DEFAULT;

 COMMIT;
 }}}

 Which is slightly strange since the initial migration never set a DEFAULT,
 so there is nothing to DROP.

 I first noticed this working with django-cms (see https://github.com/divio
 /django-cms/issues/3479). In some cases when I attempt to make a migration
 for an unrelated app, `makemigrations` will forcefully create a migration
 for the `cms` app because the settings.CMS_TEMPLATES choices have changed.
 It then makes this automatically created migration (which is output in the
 virtualenv e.g. `env/src/django-cms/cms/migrations_django`) a dependency
 for the migration I actually intended to create. There doesn't appear to
 be a way to avoid this. This means I now have a migration I actually need
 for one of my apps that is completely dependent on me creating a migration
 for a third party app, which I don't directly control, resulting in
 migrations that are broken for other developers.

 This can also happen when the choices differ in development vs deployment,
 Django will complain:
 {{{
   Your models have changes that are not yet reflected in a migration, and
 so won't be applied.
   Run 'manage.py makemigrations' to make new migrations, and then re-run
 'manage.py migrate' to apply them.
 }}}
 So far this seems to mostly be harmless if slightly confusing/annoying. I
 am not familiar with the migration internals, but since 'choices' isn't
 used (at least not on PostgreSQL) to make any actual alterations to the
 database shouldn't it ignore this attribute?

--

--
Ticket URL: <https://code.djangoproject.com/ticket/23581#comment:1>
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/068.f0de92fc257890fb8aaed5ee68210e05%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to