Opened 7 years ago

Last modified 7 years ago

#28193 closed Bug

Maximum length of database column in many-to-many through table is not updated if the foreign keyed model has a CharField primary key — at Version 3

Reported by: James Hiew Owned by: nobody
Component: Migrations Version: 1.11
Severity: Normal Keywords: manytomanyfield, primary key, varchar, max length
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by James Hiew)

If you have a model Foowith a CharField primary key, and then another model Bar which has a ManyToManyField relationship with Foo, any changes to the max_length of Foo's primary key is not reflected in the max string length of the corresponding Bar-Foo m2m table column.

Starting with the below minimal example

from django.db import models


class Foo(models.Model):
    code = models.CharField(max_length=15, primary_key=True, unique=True, auto_created=False, editable=False)
    name = models.CharField(max_length=100)


class Bar(models.Model):
    foos = models.ManyToManyField(Foo)

Run ./manage.py makemigrations then ./manage.py migrate.

Change the max_length of Foo.code to a higher value e.g. 100

from django.db import models


class Foo(models.Model):
    code = models.CharField(max_length=100, primary_key=True, unique=True, auto_created=False, editable=False)
    name = models.CharField(max_length=100)


class Bar(models.Model):
    foos = models.ManyToManyField(Foo)

Run ./manage.py makemigrations then ./manage.py migrate once more.

The final myapp_bar_foos table DDL is:

CREATE TABLE "myapp_bar_foos" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "bar_id" integer NOT NULL REFERENCES "myapp_bar" ("id"), "foo_id" varchar(15) NOT NULL REFERENCES "myapp_foo" ("code"));
CREATE UNIQUE INDEX "myapp_bar_foos_bar_id_foo_id_6037806e_uniq" ON "myapp_bar_foos" ("bar_id", "foo_id");
CREATE INDEX "myapp_bar_foos_bar_id_f5103189" ON "myapp_bar_foos" ("bar_id");
CREATE INDEX "myapp_bar_foos_foo_id_84900b21" ON "myapp_bar_foos" ("foo_id")

The foo_id column should have been updated to type varchar(100) but it remains as varchar(15).

The problem is not noticeable when using SQLite (e.g. during local development), as SQLite doesn't seem to enforce the varchar length constraints, but Postgres does, so this issue is pernicious when moving to production.

Change History (3)

comment:1 by James Hiew, 7 years ago

Summary: Maximum length of Column in through table is not updated in migrationsMaximum length of database column in many-to-many through table is not updated if the foreign keyed model has a CharField primary key

comment:2 by James Hiew, 7 years ago

Keywords: manytomanyfield primary key varchar max length added
Type: UncategorizedBug

comment:3 by James Hiew, 7 years ago

Description: modified (diff)

Fix formatting

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