#31343: Foreign key constraint to a multi-table inheritance child model is lost 
if
the child model's parent is changed
------------------------------------------------+------------------------
               Reporter:  Antonis Christofides  |          Owner:  nobody
                   Type:  Bug                   |         Status:  new
              Component:  Migrations            |        Version:  master
               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                     |
------------------------------------------------+------------------------
 = Steps to reproduce

 1. In a project using PostgreSQL, create an app `places` with the
 following models:
 {{{
 from django.db import models


 class Place(models.Model):
     name = models.CharField(max_length=50)


 class Restaurant(Place):
     serves_hot_dogs = models.BooleanField(default=False)


 class MenuItem(models.Model):
     restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
 }}}

 2. Run `./manage.py makemigrations`. It will create `0001_initial.py`.

 3. Change the models to this:
 {{{
 from django.db import models


 class Place(models.Model):
     name = models.CharField(max_length=50)


 class CommercialPlace(Place):
     business_name = models.CharField(max_length=50)


 class Restaurant(CommercialPlace):
     serves_hot_dogs = models.BooleanField(default=False)


 class MenuItem(models.Model):
     restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
 }}}

 The difference is that `Restaurant` now inherits the new
 `CommercialPlace`, whereas before it was directly inheriting `Place`. The
 `MenuItem` model is untouched.

 4. Execute `/.manage.py makemigrations`.

 At this stage it will not know what to do ("You are trying to add a non-
 nullable field 'commercialplace_ptr' to restaurant without a default").
 Select option 1 (provide a one-off default) and enter 0 as the default
 value.

 (This doesn't make sense, but it doesn't matter. What should happen here
 is for `commercialplace_ptr` to get the value `place_ptr` previously had,
 but Django can't figure this out on its own, so the developer will need to
 write it in the migration. This has nothing to do with the bug, so in this
 example we can ignore this problem.)

 Migration 0002_auto_something.py will be created as a result of this step.

 5. Execute `./manage.py sqlmigrate places 0002`.

 = Result

 The sqlmigrate output contains, among other things, this:

 {{{
 ALTER TABLE "places_restaurant" DROP COLUMN "place_ptr_id" CASCADE;
 }}}

 As a result of the CASCADE, the foreign key constraint from
 `MenuItem.restaurant` will be dropped. **No constraint is created in its
 place.**

-- 
Ticket URL: <https://code.djangoproject.com/ticket/31343>
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/049.aa0a33f710f17c7d39bf47db6feda984%40djangoproject.com.

Reply via email to