Opened 2 years ago

Last modified 11 months ago

#25012 new Bug

Migration doesn't seem to detect foreignKey type changes

Reported by: Hedde van der Heide Owned by: nobody
Component: Migrations Version: master
Severity: Normal Keywords:
Cc: Tyson Clugg 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 Hedde van der Heide)

Example:

class Foo(models.Model):
    id = models.AutoField()  # Now change this to models.CharField(primary_key=True, max_length=...) and migrate, the migration doesn't complain    

class Bar(object):
    foo = models.ForeignKey(Foo)  # but Postgres will still say Bar.foo is an Integer value.

DataError at /myapp/bar/add/
invalid input syntax for integer: "TEST"
LINE 1: ...d") VALUES (NULL, 'TEST', ...

Change History (8)

comment:1 Changed 2 years ago by Hedde van der Heide

Description: modified (diff)

comment:2 Changed 2 years ago by Hedde van der Heide

Description: modified (diff)

comment:3 Changed 2 years ago by Moritz Sichert

Component: UncategorizedMigrations
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug

Confirmed on master.

comment:4 Changed 2 years ago by Tyson Clugg

Cc: Tyson Clugg added

comment:5 Changed 20 months ago by Tim Graham

#26404 is a duplicate.

comment:6 Changed 18 months ago by Simon Charette

Keywords: postgres migrations removed
Version: 1.8master

#24954 was a duplicate for the ManyToManyField case.

comment:7 Changed 18 months ago by Simon Charette

#25733 was a duplicate for the OneToOneField case.

Last edited 18 months ago by Simon Charette (previous) (diff)

comment:8 Changed 11 months ago by Aleksi Häkli

I was able to neatly fix this with a raw SQL migration that changed the intermediary table column type.

I had the following schema in an application called documents:

class Tag(models.Model):
    # converted this `name` field to primary_key
    # previously had the default `id` AutoField as primary_key field
    # PrimaryKeyField migration in for ManyToManyField is risky!
    name = models.CharField(max_length=32, primary_key=True)

class Document(models.Model):
    tags = models.ManyToManyField(Tag, blank=True)

After changing the schema and running unit tests I discovered that I indeed to got a DatabaseError:

django.db.utils.DataError: invalid input syntax for integer: "Miss Amanda Goodwin"
LINE 1: ..."tag_id") WHERE "documents_document_tags"."tag_id" = 'Miss Aman...

Migrating with the following helped:

ALTER TABLE documents_document_tags ALTER COLUMN tag_id TYPE varchar(32);

This of course had to be added as a migration file for sane functionality in tests and migration chain:

# -*- coding: utf-8 -*-
# Migrations file example for fixing broken ManyToManyField migration from INTEGER to VARCHAR
# Generated by Django 1.10.3 on 1970-01-01 00:00
from __future__ import unicode_literals

from django.db import migrations

class Migration(migrations.Migration):
    dependencies = [
        ('documents', '0042_auto_19700101-0000'),
    ]

    operations = [
        migrations.RunSQL('ALTER TABLE documents_document_tags ALTER tag_id TYPE varchar(32);'),
    ]
Note: See TracTickets for help on using tickets.
Back to Top