Opened 4 years ago

Closed 4 years ago

#31444 closed Bug (needsinfo)

ForeignKey migrations without database changes shouldn't touch the database

Reported by: Peter Law Owned by: nobody
Component: Migrations Version: 2.2
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

Description

If you have a model like this:

class Thing(models.Model):
    user = models.ForeignKey('auth.User', related_name='+')

And you then decide to change the related name, like so:

class Thing(models.Model):
    user = models.ForeignKey('auth.User', related_name='things')

Then Django will create a migration for this change. I understand why the migration is present (all fine so far).

At least for Postgres (I've not tested elsewhere), when Django runs the migration it will end up dropping and re-adding the foreign key (which involves locking the table and having the database revalidate the ForeignKey) but nothing else.
In a production system this is at best inconvenient and at worst can significantly impact site performance for the duration of the migration (or force you to take the site offline to run the migration).

Ideally Django would detect that nothing needs to be done to the database for this migration and not emit any SQL for this migration.

There might be a general question here about why the foreign key is being dropped and re-created (and if we can avoid that, that would be even better), though I'd be happy for now with a fix just for the case of a no-op.

Change History (2)

comment:1 by Simon Charette, 4 years ago

At least for Postgres (I've not tested elsewhere), when Django runs the migration it will end up dropping and re-adding the foreign key (which involves locking the table and having the database revalidate the ForeignKey) but nothing else.
In a production system this is at best inconvenient and at worst can significantly impact site performance for the duration of the migration (or force you to take the site offline to run the migration).

Pretty sure this is solved in recent versions of Django, against which version did you reproduce?

comment:2 by Simon Charette, 4 years ago

Resolution: needsinfo
Status: newclosed

I couldn't reproduce on the latest point releases of Django 1.11, 2.0, 2.1, 2.2, 3.0, and master so this has been fixed for a long time. Please reopen if you can provide more details about how to reproduce and upgrade to 2.2 or 3.0 if you're still using an unsupported version.

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