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