Opened 13 months ago

Closed 12 months ago

Last modified 12 months ago

#22470 closed Bug (fixed)

Migrations fail with order_with_respect_to and ForeignKey to self

Reported by: Jonas Owned by: andrewgodwin
Component: Migrations Version: 1.7-beta-1
Severity: Release blocker Keywords: migrations order_with_respect_to
Cc: Jonas, shai, jezevec, beathan Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Initial migrations for an app with this kind of model setup will fail when running ./manage.py migrate:

class Parent(models.Model):
    spouse = models.ForeignKey('self')

class Child(models.Model):
    parent = models.ForeignKey(Parent)

    class Meta:
        order_with_respect_to = 'parent'

This is the resulting traceback:

  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/jonas/temp/django/django/core/management/__init__.py", line 427, in execute_from_command_line
    utility.execute()
  File "/home/jonas/temp/django/django/core/management/__init__.py", line 419, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/jonas/temp/django/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/home/jonas/temp/django/django/core/management/base.py", line 337, in execute
    output = self.handle(*args, **options)
  File "/home/jonas/temp/django/django/core/management/commands/migrate.py", line 145, in handle
    executor.migrate(targets, plan, fake=options.get("fake", False))
  File "/home/jonas/temp/django/django/db/migrations/executor.py", line 60, in migrate
    self.apply_migration(migration, fake=fake)
  File "/home/jonas/temp/django/django/db/migrations/executor.py", line 88, in apply_migration
    if self.detect_soft_applied(migration):
  File "/home/jonas/temp/django/django/db/migrations/executor.py", line 132, in detect_soft_applied
    apps = project_state.render()
  File "/home/jonas/temp/django/django/db/migrations/state.py", line 48, in render
    model.render(self.apps)
  File "/home/jonas/temp/django/django/db/migrations/state.py", line 232, in render
    body,
  File "/home/jonas/temp/django/django/db/models/base.py", line 298, in __new__
    new_class._prepare()
  File "/home/jonas/temp/django/django/db/models/base.py", line 322, in _prepare
    opts._prepare(cls)
  File "/home/jonas/temp/django/django/db/models/options.py", line 180, in _prepare
    self.order_with_respect_to = self.get_field(self.order_with_respect_to)
  File "/home/jonas/temp/django/django/db/models/options.py", line 397, in get_field
    raise FieldDoesNotExist('%s has no field named %r' % (self.object_name, name))
django.db.models.fields.FieldDoesNotExist: Child has no field named 'parent'

makemigrations creates three migrations:

  • The first migration creates the Child model without the parent field as well as the Parent model without the spouse field.
  • The second migration adds the spouse field to Parent.
  • The third migration adds parent to Child.

The error occurs in the first migration, when the _prepare() wants to access the parent field for order_with_respect_to and can't, as it doesn't exist yet.

I tried adding a test in Django proper but wasn't able to. Will keep trying but support is appreciated.

Change History (11)

comment:1 Changed 13 months ago by Jonas

  • Cc Jonas added
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 13 months ago by timo

  • Severity changed from Normal to Release blocker
  • Triage Stage changed from Unreviewed to Accepted

comment:3 Changed 13 months ago by andrewgodwin

  • Owner changed from nobody to andrewgodwin
  • Status changed from new to assigned

Urgh, this is nasty. I'm going to have to find some way of pushing back all Meta changes along with delayed ForeignKeys (this bug will also occur for index_together and unique_together among others).

comment:4 Changed 13 months ago by shai

  • Cc shai added

This is odd. I'd expect all the fields to be created immediately, and only the constraint creation to be delayed.

comment:5 Changed 13 months ago by andrewgodwin

Hmm, that might be possible - we could replace the AddField(ForeignKey) with AddField(IntegerField) (or whatever the underlying type is) and then have the second thing be the AlterField to a ForeignKey. I'll try that approach.

comment:6 Changed 12 months ago by jezevec

  • Cc jezevec added

comment:7 Changed 12 months ago by beathan

  • Cc beathan added

comment:8 Changed 12 months ago by andrewgodwin

Just noting that this will be fixed as part of the big autodetector rewrite.

comment:9 Changed 12 months ago by andrewgodwin

This didn't land in the main autodetector merge, but it can now be fixed as that's in place. I plan to add a new operation for alterations to order_with_respect_to (or perhaps just alteration of model options in general) and implement that with proper dependency to fix this.

comment:10 Changed 12 months ago by Andrew Godwin <andrew@…>

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

In e5cde2062c0fbe21476978cc318c84134bf7bc46:

[1.7.x] Fixed #22470: Full migration support for order_with_respect_to

comment:11 Changed 12 months ago by Andrew Godwin <andrew@…>

In a8ce5fdc28bdbe091476d49d014d68f8ba4353e7:

Fixed #22470: Full migration support for order_with_respect_to

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