[Django] #24260: Add migration support for logical field renames

11 views
Skip to first unread message

Django

unread,
Feb 2, 2015, 9:41:57 AM2/2/15
to django-...@googlegroups.com
#24260: Add migration support for logical field renames
----------------------------+--------------------
Reporter: pennersr | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.7
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------+--------------------
Suppose you have a legacy model, defined like this:

{{{
class Foo(models.Model):
foo_id = models.AutoField(primary_key=True)
}}}

Now, I would like to clean this up, into:

{{{
class Foo(models.Model):
id = models.AutoField(primary_key=True, db_column='foo_id')
}}}

This is only a logical name change, without any impact on the
database. Yet, there seems to be no way to convince `makemigrations`
that nothing needs to happen.

Whatever I do, it will always complain, or worse, attempt to remove
the `foo_id` altogether:

{{{
operations = [
migrations.RemoveField(
model_name='foo',
name='foo_id',
),
migrations.AddField(
model_name='foo',
name='id',
field=models.AutoField(default=0, serialize=False,
primary_key=True, db_column=b'foo_id'),
preserve_default=False,
),
]
}}}

Using South you could work around this by having empty
forwards/backwards methods. It would be nice if Django migrations
offered a way out as well.

--
Ticket URL: <https://code.djangoproject.com/ticket/24260>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 2, 2015, 10:09:50 AM2/2/15
to django-...@googlegroups.com
#24260: Add migration support for logical field renames
-----------------------------+------------------------------------
Reporter: pennersr | Owner: nobody
Type: New feature | Status: new
Component: Migrations | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------
Changes (by timgraham):

* needs_docs: => 0
* needs_better_patch: => 0
* type: Bug => New feature
* needs_tests: => 0
* stage: Unreviewed => Accepted


Comment:

I'm guessing you might be able to use the
[https://docs.djangoproject.com/en/1.7/ref/migration-
operations/#separatedatabaseandstate SeparateDatabaseAndState] operation
to achieve this, but if so, the documentation should really be improved
with an example.

--
Ticket URL: <https://code.djangoproject.com/ticket/24260#comment:1>

Django

unread,
Feb 2, 2015, 2:46:58 PM2/2/15
to django-...@googlegroups.com
#24260: Add migration support for logical field renames
-----------------------------+------------------------------------
Reporter: pennersr | Owner: nobody
Type: New feature | Status: new
Component: Migrations | Version: 1.7

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------

Comment (by timgraham):

Actually, something like simply
{{{
migrations.AlterField(


model_name='foo',
name='id',
field=models.AutoField(default=0, serialize=False, primary_key=True,
db_column=b'foo_id'),
preserve_default=False,
)
}}}

might work. Did you try that? Django needs a migration to know the field
has changed, even if no SQL is generated.

--
Ticket URL: <https://code.djangoproject.com/ticket/24260#comment:2>

Django

unread,
Feb 4, 2015, 3:16:22 AM2/4/15
to django-...@googlegroups.com
#24260: Add migration support for logical field renames
-----------------------------+------------------------------------
Reporter: pennersr | Owner: nobody
Type: New feature | Status: new
Component: Migrations | Version: 1.7

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------

Comment (by pennersr):

That does not seem to help. If I add the following migration:

{{{
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

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

operations = [
migrations.AlterField(


model_name='foo',
name='id',

field=models.AutoField(serialize=False, primary_key=True,


db_column=b'foo_id'),
preserve_default=False,
),
]
}}}

Then:

{{{
python manage.py makemigrations foo
You are trying to add a non-nullable field 'id' to foo without a default;
we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Select an option:
}}}

Putting some dummy `default=0` or something in the migration does not help
either.

--
Ticket URL: <https://code.djangoproject.com/ticket/24260#comment:3>

Django

unread,
Mar 1, 2015, 9:13:17 AM3/1/15
to django-...@googlegroups.com
#24260: Add migration support for logical field renames
-----------------------------+------------------------------------
Reporter: pennersr | Owner: nobody
Type: New feature | Status: new
Component: Migrations | Version: 1.7

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------

Comment (by MarkusH):

You should get it working with

{{{#!python
operations = [
migrations.AlterField(


model_name='foo',
name='foo_id',

field=models.AutoField(db_column='foo_id', primary_key=True,
serialize=False),
),
migrations.RenameField(
model_name='foo',
old_name='foo_id',
new_name='id',
),
]
}}}

This can be semi-automated by first ensuring the field arguments are
explicitly set for `foo_id` (`foo_id = models.AutoField(primary_key=True,
db_column='foo_id')`, then running makemigrations followed by a rename
(`id = models.AutoField(primary_key=True, db_column='foo_id')` and another
makemigrations (the latter will ask if `foo.foo_id` is being renamed to
`foo.id`).

I don't, however, see a way how Django could automatically detect these
changes in a single run, given that we have to check for renamed fields
first:
https://github.com/django/django/blob/master/django/db/migrations/autodetector.py#L183-L186
. After all, we will end up with two operations.

--
Ticket URL: <https://code.djangoproject.com/ticket/24260#comment:4>

Django

unread,
May 25, 2016, 3:01:58 AM5/25/16
to django-...@googlegroups.com
#24260: Add migration support for logical field renames
-----------------------------+------------------------------------
Reporter: pennersr | Owner: nobody
Type: New feature | Status: new
Component: Migrations | Version: 1.7

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------

Comment (by charettes):

Related to #24157 where the autodetector can't detect a rename when the
field options are also changed.

--
Ticket URL: <https://code.djangoproject.com/ticket/24260#comment:5>

Django

unread,
Jun 4, 2018, 2:32:57 PM6/4/18
to django-...@googlegroups.com
#24260: Add migration support for logical field renames
---------------------------------+------------------------------------
Reporter: Raymond Penners | Owner: nobody
Type: New feature | Status: closed
Component: Migrations | Version: 1.7
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
---------------------------------+------------------------------------
Changes (by Simon Charette):

* status: new => closed
* resolution: => fixed


Comment:

I'm pretty confident #29245 was a duplicate that will be fixed in Django
2.1 by 2156565b5bac2e6f503ad4841e2b6ed44e4de656.

--
Ticket URL: <https://code.djangoproject.com/ticket/24260#comment:6>

Reply all
Reply to author
Forward
0 new messages