#22183 closed Bug (fixed)

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

Reported by: apollo13 Owned by: andrewgodwin
Component: Migrations Version: master
Severity: Release blocker Keywords: sql, migrations, m2m
Cc: apollo13, 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 apollo13 13 months ago.
patch.diff (1.2 KB) - added by apollo13 13 months ago.

Download all attachments as: .zip

Change History (10)

Changed 13 months ago by apollo13

comment:1 Changed 13 months ago by apollo13

  • Summary changed from Migrations don't work reliably with M2M fields. to 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 13 months ago by apollo13

comment:2 Changed 13 months ago by apollo13

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 13 months ago by MarkusH

  • Cc info@… added

comment:4 Changed 13 months ago by Andrew Godwin <andrew@…>

  • Resolution set to fixed
  • Status changed from new to closed

In 1562b9896f8f614ef40fd032b1ec777280b377c1:

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

comment:5 Changed 13 months 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 13 months ago by andrewgodwin

  • Resolution fixed deleted
  • Status changed from closed to new

comment:7 Changed 13 months ago by andrewgodwin

  • Status changed from new to assigned

comment:8 Changed 13 months ago by Andrew Godwin <andrew@…>

  • Resolution set to fixed
  • Status changed from assigned to closed

In 6b078044745ee3c665051a886021c6fd1f6873b6:

Fixed #22183: Through M2Ms now correctly handled

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