#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.