summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2022-01-27 18:51:39 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-01-27 18:52:35 +0100
commit7c2d4d943b2905a8cfbb2d2f6c6fa15983b23ff1 (patch)
treeb3cff2afea69926c8b611e40987ff8c714b2ddb9 /tests
parentf4de87038ef3adfe8c67ede6c3c5519451abe6cc (diff)
[4.0.x] Fixed #33462 -- Fixed migration crash when altering type of primary key with MTI and foreign key.
This prevents duplicated operations when altering type of primary key with MTI and foreign key. Previously, a foreign key to the base model was added twice, once directly and once by the inheritance model. Thanks bcail for the report. Regression in 325d7710ce9f6155bb55610ad6b4580d31263557. Backport of e972620ada4f9ed7bc57f28e133e85c85b0a7b20 from main
Diffstat (limited to 'tests')
-rw-r--r--tests/migrations/test_operations.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py
index 11961a1f40..5e2edc5297 100644
--- a/tests/migrations/test_operations.py
+++ b/tests/migrations/test_operations.py
@@ -1600,6 +1600,73 @@ class OperationTests(OperationTestBase):
(f'{app_label}_shetlandpony', 'pony_ptr_id'),
)
+ def test_alter_field_pk_mti_and_fk_to_base(self):
+ app_label = 'test_alflpkmtiftb'
+ project_state = self.set_up_test_model(
+ app_label, mti_model=True, related_model=True,
+ )
+ operation = migrations.AlterField(
+ 'Pony',
+ 'id',
+ models.BigAutoField(primary_key=True),
+ )
+ new_state = project_state.clone()
+ operation.state_forwards(app_label, new_state)
+ self.assertIsInstance(
+ new_state.models[app_label, 'pony'].fields['id'],
+ models.BigAutoField,
+ )
+
+ def _get_column_id_type(cursor, table, column):
+ return [
+ c.type_code
+ for c in connection.introspection.get_table_description(
+ cursor,
+ f'{app_label}_{table}',
+ )
+ if c.name == column
+ ][0]
+
+ def assertIdTypeEqualsMTIFkType():
+ with connection.cursor() as cursor:
+ parent_id_type = _get_column_id_type(cursor, 'pony', 'id')
+ fk_id_type = _get_column_id_type(cursor, 'rider', 'pony_id')
+ child_id_type = _get_column_id_type(cursor, 'shetlandpony', 'pony_ptr_id')
+ self.assertEqual(parent_id_type, child_id_type)
+ self.assertEqual(parent_id_type, fk_id_type)
+
+ assertIdTypeEqualsMTIFkType()
+ # Alter primary key.
+ with connection.schema_editor() as editor:
+ operation.database_forwards(app_label, editor, project_state, new_state)
+ assertIdTypeEqualsMTIFkType()
+ if connection.features.supports_foreign_keys:
+ self.assertFKExists(
+ f'{app_label}_shetlandpony',
+ ['pony_ptr_id'],
+ (f'{app_label}_pony', 'id'),
+ )
+ self.assertFKExists(
+ f'{app_label}_rider',
+ ['pony_id'],
+ (f'{app_label}_pony', 'id'),
+ )
+ # Reversal.
+ with connection.schema_editor() as editor:
+ operation.database_backwards(app_label, editor, new_state, project_state)
+ assertIdTypeEqualsMTIFkType()
+ if connection.features.supports_foreign_keys:
+ self.assertFKExists(
+ f'{app_label}_shetlandpony',
+ ['pony_ptr_id'],
+ (f'{app_label}_pony', 'id'),
+ )
+ self.assertFKExists(
+ f'{app_label}_rider',
+ ['pony_id'],
+ (f'{app_label}_pony', 'id'),
+ )
+
@skipUnlessDBFeature('supports_foreign_keys')
def test_alter_field_reloads_state_on_fk_with_to_field_target_type_change(self):
app_label = 'test_alflrsfkwtflttc'