#29182: SQLite database migration breaks ForeignKey constraint, leaving
<table_name>__old in db schema
----------------------------------+------------------------------------
     Reporter:  ezaquarii         |                    Owner:  nobody
         Type:  Bug               |                   Status:  new
    Component:  Migrations        |                  Version:  2.0
     Severity:  Release blocker   |               Resolution:
     Keywords:  sqlite migration  |             Triage Stage:  Accepted
    Has patch:  0                 |      Needs documentation:  0
  Needs tests:  0                 |  Patch needs improvement:  0
Easy pickings:  0                 |                    UI/UX:  0
----------------------------------+------------------------------------
Changes (by Florian Apolloner):

 * type:  Cleanup/optimization => Bug
 * severity:  Normal => Release blocker


Comment:

 Changing this to a full blown bug and release blocker since I am able to
 reproduce this with `./manage.py migrate` and very simple app.

 Relevant versions:
 Sqlite: 3.26.0 2018-12-01 12:34:55
 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt1
 python sqlite3 version: 2.6.0

 Same test models:
 {{{
 #!python
 from django.db import models

 class File(models.Model):
     content = models.ForeignKey("FileContent", on_delete=models.PROTECT)

 class FileContent(models.Model):
     pass

 class PlayBook(models.Model):
     file = models.ForeignKey("File", on_delete=models.PROTECT)
 }}}

 This generates the following initial migration (on latest master):
 {{{
 #!python
 # Generated by Django 2.2.dev20181204152138 on 2018-12-04 16:49

 from django.db import migrations, models
 import django.db.models.deletion


 class Migration(migrations.Migration):

     initial = True

     dependencies = [
     ]

     operations = [
         migrations.CreateModel(
             name='File',
             fields=[
                 ('id', models.AutoField(auto_created=True,
 primary_key=True, serialize=False, verbose_name='ID')),
             ],
         ),
         migrations.CreateModel(
             name='FileContent',
             fields=[
                 ('id', models.AutoField(auto_created=True,
 primary_key=True, serialize=False, verbose_name='ID')),
             ],
         ),
         migrations.CreateModel(
             name='PlayBook',
             fields=[
                 ('id', models.AutoField(auto_created=True,
 primary_key=True, serialize=False, verbose_name='ID')),
                 ('file',
 models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
 to='testing.File')),
             ],
         ),
         migrations.AddField(
             model_name='file',
             name='content',
 field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
 to='testing.FileContent'),
         ),
     ]
 }}}

 Running this migration results in the following schema in SQLite:
 {{{
 #!sql
 CREATE TABLE IF NOT EXISTS "django_migrations"(
   "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
   "app" varchar(255) NOT NULL,
   "name" varchar(255) NOT NULL,
   "applied" datetime NOT NULL
 );
 CREATE TABLE IF NOT EXISTS "testing_filecontent"(
   "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT
 );
 CREATE TABLE IF NOT EXISTS "testing_playbook"(
   "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
   "file_id" integer NOT NULL REFERENCES "testing_file__old"("id")
 DEFERRABLE INITIALLY DEFERRED
 );
 CREATE TABLE IF NOT EXISTS "testing_file"(
   "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
   "content_id" integer NOT NULL REFERENCES "testing_filecontent"("id")
 DEFERRABLE INITIALLY DEFERRED
 );
 CREATE INDEX "testing_playbook_file_id_debe0476" ON "testing_playbook"(
   "file_id"
 );
 CREATE INDEX "testing_file_content_id_4682b86d" ON "testing_file"(
   "content_id"
 );
 }}}

 From the looks of it, we will need to do some similar to
 
https://github.com/django/django/blob/196b420fcb0cbdd82970e2b9aea80251bde82056/django/db/backends/sqlite3/schema.py#L108-L121
 whenever we rename a table which has foreignkeys pointing to it.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/29182#comment:8>
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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/067.82727c654fc1d1707f151f9060ccc39b%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to