[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 cc22b009e0
from master
This commit is contained in:
parent
10ea9ef012
commit
8ca0eb2af7
|
@ -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)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -376,6 +376,41 @@ class ExecutorTests(MigrationTestBase):
|
||||||
]
|
]
|
||||||
self.assertEqual(call_args_list, expected)
|
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):
|
class FakeLoader(object):
|
||||||
def __init__(self, graph, applied):
|
def __init__(self, graph, applied):
|
||||||
|
|
Loading…
Reference in New Issue