diff options
| author | Markus Holtermann <info@markusholtermann.eu> | 2015-02-11 10:14:53 +0100 |
|---|---|---|
| committer | Markus Holtermann <info@markusholtermann.eu> | 2015-02-16 19:37:51 +0100 |
| commit | 8ca0eb2af70b7fbfd9689553d40ef6023433f94e (patch) | |
| tree | 8b8e5eb50ac03f889a4427e03ecb6ed5f8cec7cf | |
| parent | 10ea9ef012cc11c9ae67ab4ba5d84e0d5d192732 (diff) | |
[1.8.x] Refs #24264 -- Added failing test case for updating a FK when changing a PK
When the primary key column is altered, foreign keys of referencing
models must be aware of a possible data type change as well and thus
need to be re-rendered.
Thanks Tim Graham for the report.
Backport of cc22b009e05456e3d9cf3c152fe47fa27772be5e from master
9 files changed, 97 insertions, 0 deletions
diff --git a/tests/migrations/migrations_test_apps/alter_fk/__init__.py b/tests/migrations/migrations_test_apps/alter_fk/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/migrations/migrations_test_apps/alter_fk/__init__.py diff --git a/tests/migrations/migrations_test_apps/alter_fk/author_app/__init__.py b/tests/migrations/migrations_test_apps/alter_fk/author_app/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/migrations/migrations_test_apps/alter_fk/author_app/__init__.py diff --git a/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0001_initial.py new file mode 100644 index 0000000000..8df44dfeef --- /dev/null +++ b/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0001_initial.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Author', + fields=[ + ('id', models.AutoField(serialize=False, auto_created=True, primary_key=True)), + ('name', models.CharField(max_length=50)), + ], + ), + ] diff --git a/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0002_alter_id.py b/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0002_alter_id.py new file mode 100644 index 0000000000..ffce7dbd70 --- /dev/null +++ b/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0002_alter_id.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('author_app', '0001_initial'), + ('book_app', '0001_initial'), # Forces the book table to alter the FK + ] + + operations = [ + migrations.AlterField( + model_name='author', + name='id', + field=models.CharField(max_length=10, primary_key=True), + ), + ] diff --git a/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/__init__.py b/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/__init__.py diff --git a/tests/migrations/migrations_test_apps/alter_fk/book_app/__init__.py b/tests/migrations/migrations_test_apps/alter_fk/book_app/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/migrations/migrations_test_apps/alter_fk/book_app/__init__.py diff --git a/tests/migrations/migrations_test_apps/alter_fk/book_app/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/alter_fk/book_app/migrations/0001_initial.py new file mode 100644 index 0000000000..c929e4f075 --- /dev/null +++ b/tests/migrations/migrations_test_apps/alter_fk/book_app/migrations/0001_initial.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('author_app', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Book', + fields=[ + ('id', models.AutoField(serialize=False, auto_created=True, primary_key=True)), + ('title', models.CharField(max_length=50)), + ('author', models.ForeignKey('author_app.Author')), + ], + ), + ] diff --git a/tests/migrations/migrations_test_apps/alter_fk/book_app/migrations/__init__.py b/tests/migrations/migrations_test_apps/alter_fk/book_app/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/migrations/migrations_test_apps/alter_fk/book_app/migrations/__init__.py diff --git a/tests/migrations/test_executor.py b/tests/migrations/test_executor.py index b88307ceea..b05eb04514 100644 --- a/tests/migrations/test_executor.py +++ b/tests/migrations/test_executor.py @@ -376,6 +376,41 @@ class ExecutorTests(MigrationTestBase): ] self.assertEqual(call_args_list, expected) + @override_settings( + INSTALLED_APPS=[ + "migrations.migrations_test_apps.alter_fk.author_app", + "migrations.migrations_test_apps.alter_fk.book_app", + ] + ) + def test_alter_id_type_with_fk(self): + try: + executor = MigrationExecutor(connection) + self.assertTableNotExists("author_app_author") + self.assertTableNotExists("book_app_book") + # Apply initial migrations + executor.migrate([ + ("author_app", "0001_initial"), + ("book_app", "0001_initial"), + ]) + self.assertTableExists("author_app_author") + self.assertTableExists("book_app_book") + # Rebuild the graph to reflect the new DB state + executor.loader.build_graph() + + # Apply PK type alteration + executor.migrate([("author_app", "0002_alter_id")]) + + # Rebuild the graph to reflect the new DB state + executor.loader.build_graph() + finally: + # We can't simply unapply the migrations here because there is no + # implicit cast from VARCHAR to INT on the database level. + with connection.schema_editor() as editor: + editor.execute(editor.sql_delete_table % {"table": "book_app_book"}) + editor.execute(editor.sql_delete_table % {"table": "author_app_author"}) + self.assertTableNotExists("author_app_author") + self.assertTableNotExists("book_app_book") + class FakeLoader(object): def __init__(self, graph, applied): |
