#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.