Opened 3 years ago

Closed 3 years ago

#22183 closed Bug (fixed)

Migrations don't work with custom through table on M2M fields

Reported by: Florian Apolloner Owned by: Andrew Godwin
Component: Migrations Version: master
Severity: Release blocker Keywords: sql, migrations, m2m
Cc: Florian Apolloner, info@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Given those models:

from django.db import models
#from taggit.managers import *


class M2M(models.Model):
    test1 = models.ForeignKey('Test1', related_name='+')
    test2 = models.ForeignKey('Test2', related_name='+')

class Test1(models.Model):
    pass

class Test2(models.Model):
    m2m = models.ManyToManyField(Test1, through=M2M)

#class Test3(models.Model):
#    tags = TaggableManager()

The created schema will look like:

CREATE TABLE "testing_test1" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT);
CREATE TABLE "testing_test2" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT);
CREATE TABLE "testing_test2_m2m" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "test2_id" integer NOT NULL REFERENCES "testing_test2" ("id"), "test1_id" integer NOT NULL REFERENCES "testing_test1" ("id"), UNIQUE ("test2_id", "test1_id"));
CREATE TABLE "testing_m2m" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "test1_id" integer NOT NULL REFERENCES "testing_test1" ("id"), "test2_id" integer NOT NULL REFERENCES "testing_test2" ("id"));

The issue here is that there is a table named "testing_test2_m2m" which shouldn't be there!

Attached you will find a full project demonstrating this issue.

Attachments (2)

testing.zip (6.5 KB) - added by Florian Apolloner 3 years ago.
patch.diff (1.2 KB) - added by Florian Apolloner 3 years ago.

Download all attachments as: .zip

Change History (10)

Changed 3 years ago by Florian Apolloner

Attachment: testing.zip added

comment:1 Changed 3 years ago by Florian Apolloner

Summary: Migrations don't work reliably with M2M fields.Migrations don't work with custom through table on M2M fields

The main issue seems to be that the migration is created as follows:

        migrations.CreateModel(
            name='Test2',
            fields=[
                (u'id', models.AutoField(verbose_name=u'ID', serialize=False, auto_created=True, primary_key=True)),
                ('m2m', models.ManyToManyField(to='testing.Test1')),
            ],
            options={
            },
            bases=(models.Model,),
        ),

This means the through property is not considered, and as such Django correctly tries to create testing_test2_m2m too.

Changed 3 years ago by Florian Apolloner

Attachment: patch.diff added

comment:2 Changed 3 years ago by Florian Apolloner

Attached patch fixes it for me; but now the migrations are created oddly:

Migrations for 'testing':
  0001_initial.py:
    - Create model Test1
    - Create model M2M
    - Create model Test2
  0001_m2m_test2.py:
    - Add field test2 to m2m

If it would create Test1 and Test2 first it wouldn't need two migrations.

comment:3 Changed 3 years ago by Markus Holtermann

Cc: info@… added

comment:4 Changed 3 years ago by Andrew Godwin <andrew@…>

Resolution: fixed
Status: newclosed

In 1562b9896f8f614ef40fd032b1ec777280b377c1:

Fixed #22183: Don't make a table for M2Ms with through=

comment:5 Changed 3 years ago by Andrew Godwin <andrew@…>

In 8ce3ea687cfae0bc47fcf023cb1f523dae4664ef:

Revert "Fixed #22183: Don't make a table for M2Ms with through="

This reverts commit 1562b9896f8f614ef40fd032b1ec777280b377c1.

comment:6 Changed 3 years ago by Andrew Godwin

Resolution: fixed
Status: closednew

comment:7 Changed 3 years ago by Andrew Godwin

Status: newassigned

comment:8 Changed 3 years ago by Andrew Godwin <andrew@…>

Resolution: fixed
Status: assignedclosed

In 6b078044745ee3c665051a886021c6fd1f6873b6:

Fixed #22183: Through M2Ms now correctly handled

Note: See TracTickets for help on using tickets.
Back to Top