#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 [email protected].
To post to this group, send email to [email protected].
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