Opened 13 months ago

Closed 13 months ago

Last modified 13 months ago

#22300 closed Uncategorized (fixed)

Migrations fail if a relation field is added where a non-rel field was

Reported by: melinath Owned by: nobody
Component: Migrations Version: master
Severity: Normal Keywords:
Cc: melinath Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Scenario is this: I have deleted a CharField with choices and replaced it with a ForeignKey to a new table. When Django tries to detect whether this is a "rename", it chokes because it *assumes* that any rel field that was added and might have been renamed was previously *also* a rel field.

Traceback:

Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File ".../django/django/core/management/__init__.py", line 427, in execute_from_command_line
    utility.execute()
  File ".../django/django/core/management/__init__.py", line 419, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File ".../django/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File ".../django/django/core/management/base.py", line 337, in execute
    output = self.handle(*args, **options)
  File ".../django/django/core/management/commands/makemigrations.py", line 99, in handle
    changes = autodetector.changes(graph=loader.graph, trim_to_apps=app_labels or None)
  File ".../django/django/db/migrations/autodetector.py", line 33, in changes
    changes = self._detect_changes()
  File ".../django/django/db/migrations/autodetector.py", line 272, in _detect_changes
    old_rel_to = old_field_dec[2]['to']
KeyError: 'to'

Should be easy fix - just changing this:

                    if field.rel and field.rel.to:
                        old_rel_to = old_field_dec[2]['to']

to this:

                    if field.rel and field.rel.to and 'to' in old_field_dec[2]:
                        old_rel_to = old_field_dec[2]['to']

Change History (5)

comment:1 Changed 13 months ago by bmispelon

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Hi,

I can't seem to be able to reproduce this.

I used this model:

class Foo(models.Model):
    foo = models.CharField(max_length=10)

After that, I ran makemigrations which correctly created the migration file.
I then changed the models to:

class Bar(models.Model):
    pass

class Foo(models.Model):
    foo = models.ForeignKey(Bar)

Running makemigrations again works and correctly creates a second migration files.

Can you show us the models you are using?

Thanks.

comment:2 Changed 13 months ago by melinath

My pull request (https://github.com/django/django/pull/2452) includes a new test that fails without this fix.

comment:3 Changed 13 months ago by melinath

  • Cc melinath added

comment:4 Changed 13 months ago by Tim Graham <timograham@…>

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

In 35ed792cf248d6b245e299d13fe47b56f4c6bf42:

Fixed #22300 -- Fixed crash in migrations when changing non-relational field to relational.

comment:5 Changed 13 months ago by Tim Graham <timograham@…>

In b4f165fe941b1aaca49e417330103a02fecb2e85:

[1.7.x] Fixed #22300 -- Fixed crash in migrations when changing non-relational field to relational.

Backport of 35ed792cf2 from master

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