Opened 8 years ago

Closed 8 years ago

#25521 closed Cleanup/optimization (needsinfo)

squashmigrations tries to add foreign keys to removed models

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


I squashed a bunch of migrations in an app we'll call "foo". There was something like this going on:

  • on foo.Foo add ForeignKey to bar.Bar
  • on foo.Foo remove ForeignKey to bar.Bar
  • remove model bar.Bar

this ended up with a squashed migration with both AddField and RemoveField in it, which seems inefficient but might have worked. The problem was that, since the target model had been entirely removed in the depended-upon state, the AddField to it didn't work at all. (and failed with some misleading message in BaseDatabaseSchemaEditor.add_field about unicode has no attribute _meta.)

This was in Django 1.8.5. Haven't tried other versions.

Change History (1)

comment:1 by Tim Graham, 8 years ago

Resolution: needsinfo
Status: newclosed
Type: UncategorizedCleanup/optimization

I think we'll need more specific steps to reproduce the issue. Here's what I tried:

$ python makemigrations
Migrations for 'bar':
    - Create model Bar: class Bar(models.Model): pass
Migrations for 'foo':
    - Create model Foo: class Foo(models.Model): pass

$ python makemigrations
Migrations for 'foo':
    - Add field bar to foo: bar = models.ForeignKey('bar.Bar', null=True, blank=True)

$ python makemigrations
Migrations for 'foo':
    - Remove field bar from foo

$ python makemigrations
Migrations for 'bar':
    - Delete model Bar

$ python squashmigrations foo 0003
Will squash the following migrations:
 - 0001_initial
 - 0002_foo_bar
 - 0003_remove_foo_bar
Do you wish to proceed? [yN] y
  Optimized from 3 operations to 1 operations.
Created new squashed migration /home/tim/code/mysite/foo/migrations/
  You should commit this migration but leave the old ones in place;
  the new migration will be used for new installs. Once you are sure
  all instances of the codebase have applied the migrations you squashed,
  you can delete them.

$ python migrate
Operations to perform:
  Apply all migrations: bar, sessions, auth, admin, contenttypes, polls, foo
Running migrations:
  Rendering model states... DONE
  Applying bar.0001_initial... OK
  Applying bar.0002_delete_bar... OK
  Applying foo.0001_squashed_0003_remove_foo_bar... OK

Tested at a76309f007fff6957f39190b06f8a9055f73130f (Django

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