Opened 6 years ago

Last modified 6 years ago

#28846 closed Bug

autogenerated table for ManyToMany relation does not include UNIQUE constraint if any other field is changed — at Version 2

Reported by: Yevhen Kozlov Owned by: nobody
Component: Migrations Version: 1.11
Severity: Normal Keywords: SQLite, migration, manyToMany
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Yevhen Kozlov)

  1. create a models.py, makemigrations for them
from django.db import models

class Test(models.Model):
	pass

class Test2(models.Model):
	title = models.CharField(max_length=50)
  1. add manyToMany field only, makemigrations:
from django.db import models

class Test(models.Model):
	pass

class Test2(models.Model):
	title = models.CharField(max_length=50)
	tests = models.ManyToManyField(Test)


Check with sqlmigrate there is table ..._test2_test with UNIQUE INDEX:

CREATE TABLE "m2m_test2_tests" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "test2_id" integer NOT NULL REFERENCES "m2m_test2" ("id"), "test_id" integer NOT NULL REFERENCES "m2m_test" ("id"));
CREATE UNIQUE INDEX "m2m_test2_tests_test2_id_test_id_c4708311_uniq" ON "m2m_test2_tests" ("test2_id", "test_id");
CREATE INDEX "m2m_test2_tests_test2_id_de2c1678" ON "m2m_test2_tests" ("test2_id");
CREATE INDEX "m2m_test2_tests_test_id_9723a1f8" ON "m2m_test2_tests" ("test_id");
  1. drop migration created at step 1 and change title field additionally(say, set max_length=100)
from django.db import models

class Test(models.Model):
	pass

class Test2(models.Model):
	title = models.CharField(max_length=100)
	tests = models.ManyToManyField(Test)

Then run makemigrations and check its output:

BEGIN;
--
-- Add field tests to test2
--
CREATE TABLE "m2m_test2_tests" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "test2_id" integer NOT NULL REFERENCES "m2m_test2" ("id"), "test_id" integer NOT NULL REFERENCES "m2m_test" ("id"));
--
-- Alter field title on test2
--
ALTER TABLE "m2m_test2" RENAME TO "m2m_test2__old";
CREATE TABLE "m2m_test2" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(50) NOT NULL);
INSERT INTO "m2m_test2" ("id", "title") SELECT "id", "title" FROM "m2m_test2__old";
DROP TABLE "m2m_test2__old";
COMMIT;

So no UNIQUE constraint is generated for automatically created table if there is any other field changed in the same migration.

Change History (2)

comment:1 by Simon Charette, 6 years ago

In order to facilitate reproduction could you precise what you mean by _drop migration created at step 1_.

Does that mean deleting the migration file and dropping the database? Are you unapplying the migration before deleting it? Can you reproduce from starting from the second model state (step 2.)?

Thanks!

comment:2 by Yevhen Kozlov, 6 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top