[Django] #23101: Changing name of M2MField while db_table keeps table name unchanged leads to spurious migration that changes table name

23 views
Skip to first unread message

Django

unread,
Jul 25, 2014, 3:37:03 PM7/25/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
---------------------------------+----------------------
Reporter: maney@… | Owner: nobody
Type: Uncategorized | Status: new
Component: Migrations | Version: 1.7-rc-1
Severity: Release blocker | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+----------------------
This is the terse version, I'm going to revisit this later as I think this
and #22975 share similar root cause: using the apparent/default name and
overlooking the db_table that actually sets the table's name.

In Model "Some", have a field like

x = ManyToManyField("Other") # table name app_some_x

Change that to

x_set = ManyToManyField("Other", db_table="app_some_x")

which doesn't actually change anything in the schema, but the migration
sees it as a rename of the intermediate table, generates a migration, and
changes the name. At this point you can observe in the shell that eg.,
Some.x_set.field.m2m_db_table() -> app_some_x, but the table in the
database has been migrated to app_some_x_set.

(caveat: the above hasn't been tested per se, I'm summarizing to get this
on record before I have to go. Marked as 1.7, but while chatting with
Andrew I did check it against master - no change.)

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

Django

unread,
Jul 26, 2014, 6:02:03 AM7/26/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
---------------------------------+------------------------------------
Reporter: maney@… | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.7-rc-1
Severity: Release blocker | 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 bmispelon):

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


Comment:

Hi,

I cna reproduce the issue with a very simple scenario and it seems quite
serious.

Using these models:
{{{#!python
class Foo(models.Model):
pass


class Bar(models.Model):
foos = models.ManyToManyField("Foo", db_table='custom_table')
}}}

Running `manage.py makemigrations` and `manage.py migrate` creates a table
called `<app_name>__bar_foos` instead of `custom_table`.

This works fine in 1.6 so it's definitely a release blocker.

Thanks.

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

Django

unread,
Jul 26, 2014, 12:02:17 PM7/26/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
-------------------------------------+-------------------------------------
Reporter: maney@… | Owner:
Type: Bug | abraham.martin
Component: Migrations | Status: assigned
Severity: Release blocker | Version: 1.7-rc-1
Keywords: | Resolution:
Has patch: 0 | Triage Stage: Accepted
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by abraham.martin):

* owner: nobody => abraham.martin
* status: new => assigned


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

Django

unread,
Jul 26, 2014, 12:59:22 PM7/26/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
-------------------------------------+-------------------------------------
Reporter: maney@… | Owner:
Type: Bug | abraham.martin
Component: Migrations | Status: closed

Severity: Release blocker | Version: 1.7-rc-1
Keywords: | Resolution: fixed

Has patch: 0 | Triage Stage: Accepted
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Abraham Martin <abraham@…>):

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


Comment:

In [changeset:"999758fc7a2d6fcb01eb40de937d4420f884788d"]:
{{{
#!CommitTicketReference repository=""
revision="999758fc7a2d6fcb01eb40de937d4420f884788d"
Fixed #23101 db_table wasn't copied in deconstruct
}}}

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

Django

unread,
Jul 26, 2014, 12:59:23 PM7/26/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
-------------------------------------+-------------------------------------
Reporter: maney@… | Owner:
Type: Bug | abraham.martin
Component: Migrations | Status: closed
Severity: Release blocker | Version: 1.7-rc-1
Keywords: | Resolution: fixed
Has patch: 0 | Triage Stage: Accepted
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Andrew Godwin <andrew@…>):

In [changeset:"37f8a83ad050a1040712876002edcbfc0b057603"]:
{{{
#!CommitTicketReference repository=""
revision="37f8a83ad050a1040712876002edcbfc0b057603"
Merge pull request #2977 from abrahammartin/stable/1.7.x

Fixed #23101 db_table wasn't copied in deconstruct
}}}

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

Django

unread,
Jul 26, 2014, 1:00:54 PM7/26/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
-------------------------------------+-------------------------------------
Reporter: maney@… | Owner:
Type: Bug | abraham.martin
Component: Migrations | Status: closed
Severity: Release blocker | Version: 1.7-rc-1
Keywords: | Resolution: fixed
Has patch: 0 | Triage Stage: Accepted
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Andrew Godwin <andrew@…>):

In [changeset:"e1347e9253821a31f9896de9eb993e2376e7398f"]:
{{{
#!CommitTicketReference repository=""
revision="e1347e9253821a31f9896de9eb993e2376e7398f"


Fixed #23101 db_table wasn't copied in deconstruct

Forward port of 999758fc7a2d6fcb01eb40de937d4420f884788d from
stable/1.7.x
}}}

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

Django

unread,
Jul 28, 2014, 11:50:25 AM7/28/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
-------------------------------------+-------------------------------------
Reporter: maney@… | Owner:
Type: Bug | abraham.martin
Component: Migrations | Status: new
Severity: Release blocker | Version: 1.7-rc-2
Keywords: | Resolution:

Has patch: 0 | Triage Stage: Accepted
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by maney@…):

* status: closed => new
* version: 1.7-rc-1 => 1.7-rc-2
* resolution: fixed =>


Comment:

The changes in RC2 fix the initial creation, but do little or nothing for
the second migration - that still such a mess that I'm not even sure how
many ways it fails, though I believe the error reported is the same as
ever:

OperationalError: table "x_three_ring" already exists

This is the migration from model-0001 (the initial state) to model-0002

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

Django

unread,
Jul 28, 2014, 1:59:55 PM7/28/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
-------------------------------------+-------------------------------------
Reporter: maney@… | Owner:
Type: Bug | abraham.martin
Component: Migrations | Status: new
Severity: Release blocker | Version: 1.7-rc-2
Keywords: | Resolution:
Has patch: 0 | Triage Stage: Accepted
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by andrewgodwin):

I cannot replicate - running the models.py files as supplied works
perfectly. Can you verify that this still fails for you on the latest
master?

--
Ticket URL: <https://code.djangoproject.com/ticket/23101#comment:7>

Django

unread,
Jul 28, 2014, 2:32:05 PM7/28/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
-------------------------------------+-------------------------------------
Reporter: maney@… | Owner:
Type: Bug | abraham.martin
Component: Migrations | Status: new
Severity: Release blocker | Version: 1.7-rc-2
Keywords: | Resolution:
Has patch: 0 | Triage Stage: Accepted
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mattias Linnap <mattias@…>):

On both 1.7 RC2 and master, makemigrations and migrate run without errors.
For models One and Two it asks you if you renamed the models. But for
models Three and Four, the old fields are removed and new fields are added
instead of being detected as renames:
{{{
Did you rename the foo.One model to Onesie? [y/N] y
Did you rename the foo.Two model to Twosies? [y/N] y
Migrations for 'foo':
0002_auto_20140728_1821.py:
- Rename model One to Onesie
- Rename model Two to Twosies
- Add field ring to four
- Add field ringsies to three
- Remove field ringsie from four
- Remove field ring from three
}}}

This may or may not be correct, depending on how clever the rename
detector is supposed to be?

--
Ticket URL: <https://code.djangoproject.com/ticket/23101#comment:8>

Django

unread,
Jul 29, 2014, 12:39:32 PM7/29/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
-------------------------------------+-------------------------------------
Reporter: maney@… | Owner:
Type: Bug | abraham.martin
Component: Migrations | Status: closed

Severity: Release blocker | Version: 1.7-rc-2
Keywords: | Resolution: fixed

Has patch: 0 | Triage Stage: Accepted
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Andrew Godwin <andrew@…>):

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


Comment:

In [changeset:"a338e0773592ce4030407428c77815a713b6c9c7"]:
{{{
#!CommitTicketReference repository=""
revision="a338e0773592ce4030407428c77815a713b6c9c7"
Fixed #23101: Prefer doing deletes before creates in autodetector.

Makes declined or missed renames still work (but drop data).
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/23101#comment:9>

Django

unread,
Jul 29, 2014, 12:39:34 PM7/29/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
-------------------------------------+-------------------------------------
Reporter: maney@… | Owner:
Type: Bug | abraham.martin
Component: Migrations | Status: closed
Severity: Release blocker | Version: 1.7-rc-2
Keywords: | Resolution: fixed
Has patch: 0 | Triage Stage: Accepted
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Andrew Godwin <andrew@…>):

In [changeset:"0a4fbf4e13b194383f9eecc0af337a50fb6dfe98"]:
{{{
#!CommitTicketReference repository=""
revision="0a4fbf4e13b194383f9eecc0af337a50fb6dfe98"
[1.7.x] Fixed #23101: Prefer doing deletes before creates in autodetector.

Makes declined or missed renames still work (but drop data).
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/23101#comment:10>

Django

unread,
Jul 29, 2014, 12:40:42 PM7/29/14
to django-...@googlegroups.com
#23101: Changing name of M2MField while db_table keeps table name unchanged leads
to spurious migration that changes table name
-------------------------------------+-------------------------------------
Reporter: maney@… | Owner:
Type: Bug | abraham.martin
Component: Migrations | Status: closed
Severity: Release blocker | Version: 1.7-rc-2
Keywords: | Resolution: fixed
Has patch: 0 | Triage Stage: Accepted
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by andrewgodwin):

The rename detector prefers false negatives rather than false positives,
so this is expected behaviour.

However, declining or missing the rename was making django emit a CREATE
then a DELETE for the fields in that order, rather than (correctly) DELETE
then CREATE. I've fixed this, so at least it'll run without errors.

--
Ticket URL: <https://code.djangoproject.com/ticket/23101#comment:11>

Reply all
Reply to author
Forward
0 new messages