#34417: AlterField migration on ForeignKey field re-creates foreign key 
constraints
unnecessarily
------------------------------------------------+------------------------
               Reporter:  Ömer Faruk Abacı      |          Owner:  nobody
                   Type:  Cleanup/optimization  |         Status:  new
              Component:  Migrations            |        Version:  4.1
               Severity:  Normal                |       Keywords:
           Triage Stage:  Unreviewed            |      Has patch:  0
    Needs documentation:  0                     |    Needs tests:  0
Patch needs improvement:  0                     |  Easy pickings:  0
                  UI/UX:  0                     |
------------------------------------------------+------------------------
 Let's assume that we have the following models:

 {{{
 class Bar(models.Model):
     pass

 class Foo(models.Model):
     bar = models.ForeignKey(Bar, related_name="foos",
 on_delete=models.CASCADE)
 }}}

 The migration that creates these models will add an index to the `bar`
 field of `Foo` model, this is well-documented and there is no problem up
 until now. But when we do the following change to drop the index on the
 ForeignKey field:


 {{{
 class Foo(models.Model):
     bar = models.ForeignKey(..., db_index=False)
 }}}

 Then we have a migration that results in the following SQL statement:


 {{{
 BEGIN;
 --
 -- Alter field bar on foo
 --
 SET CONSTRAINTS "foos_foo_bar_id_efb062ad_fk_foos_bar_id" IMMEDIATE;
 ALTER TABLE "foos_foo"
     DROP CONSTRAINT "foos_foo_bar_id_efb062ad_fk_foos_bar_id";

 DROP INDEX IF EXISTS "foos_foo_bar_id_efb062ad";

 ALTER TABLE "foos_foo" ADD CONSTRAINT
 "foos_foo_bar_id_efb062ad_fk_foos_bar_id"
     FOREIGN KEY ("bar_id")
     REFERENCES "bars_bar" ("id")
     DEFERRABLE INITIALLY DEFERRED;
 COMMIT;
 }}}

 I believe that we shouldn't be needing to re-create the FK constraint, so
 the following SQL should suffice:


 {{{
 BEGIN;
 --
 -- Alter field bar on foo
 --
 DROP INDEX IF EXISTS "foos_foo_bar_id_efb062ad";
 COMMIT;
 }}}

 Actually the main problem here is that dropping & adding constraints locks
 the entire table, and it might be catastrophic for some live production
 databases. IMHO this should either be documented or refactored. I look
 forward to hear your opinions on this, thank you in advance!

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34417>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070186eb3b4ff8-5df83534-8eac-4cf6-a822-16be56611ad6-000000%40eu-central-1.amazonses.com.

Reply via email to