Opened 10 years ago

Last modified 4 years ago

#25012 closed Bug

Migrations don't make foreign key type changes — at Version 12

Reported by: Hedde van der Heide Owned by: nobody
Component: Migrations Version: dev
Severity: Normal Keywords: migrations
Cc: Tyson Clugg, Samuel Bishop 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 Tim Graham)

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 (12)

comment:1 by Hedde van der Heide, 10 years ago

Description: modified (diff)

comment:2 by Hedde van der Heide, 10 years ago

Description: modified (diff)

comment:3 by Moritz Sichert, 10 years ago

Component: UncategorizedMigrations
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug

Confirmed on master.

comment:4 by Tyson Clugg, 9 years ago

Cc: Tyson Clugg added

comment:5 by Tim Graham, 9 years ago

#26404 is a duplicate.

comment:6 by Simon Charette, 9 years ago

Keywords: postgres migrations removed
Version: 1.8master

#24954 was a duplicate for the ManyToManyField case.

comment:7 by Simon Charette, 9 years ago

#25733 was a duplicate for the OneToOneField case.

Last edited 9 years ago by Simon Charette (previous) (diff)

comment:8 by Aleksi Häkli, 8 years ago

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);'),
    ]

comment:9 by Andrew Badr, 6 years ago

If this is the same as #29787, then 45ded053b1f4320284aa5dac63052f6d1baefea9 and b8a2f3c2d66aa15af4be745a576609b958a853c0 might be useful commits to look at.

comment:10 by Samuel Bishop, 5 years ago

Cc: Samuel Bishop added
Keywords: migrations added

comment:11 by Paul Schreiber, 4 years ago

I ran in to this today (Django 3.1.4). The workaround was to

UPDATE myapp.mytable set my_fk_column = NULL;

and re-run the migration.

comment:12 by Tim Graham, 4 years ago

Description: modified (diff)
Summary: Migration doesn't seem to detect foreignKey type changesMigrations don't make foreign key type changes
Note: See TracTickets for help on using tickets.
Back to Top