diff options
| author | Tim Graham <timograham@gmail.com> | 2017-06-30 14:51:08 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-12-01 19:09:36 -0500 |
| commit | b8a2f3c2d66aa15af4be745a576609b958a853c0 (patch) | |
| tree | 02409c44ede8a96005a985406a76daeca782077b /tests | |
| parent | f319e7abad145ddcb1017293b5cdb7e09a92ee85 (diff) | |
[1.11.x] Fixed #28305 -- Fixed "Cannot change column 'x': used in a foreign key constraint" crash on MySQL with a sequence of AlterField or RenameField operations.
Regression in 45ded053b1f4320284aa5dac63052f6d1baefea9.
Backport of c3e0adcad8d8ba94b33cabd137056166ed36dae0 from master
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/migrations/test_operations.py | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index 64ae395d94..0899e92a3d 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -1324,6 +1324,83 @@ class OperationTests(OperationTestBase): operation.database_backwards("test_alflpkfk", editor, new_state, project_state) assertIdTypeEqualsFkType() + def test_alter_field_reloads_state_on_fk_target_changes(self): + """ + If AlterField doesn't reload state appropriately, the second AlterField + crashes on MySQL due to not dropping the PonyRider.pony foreign key + constraint before modifying the column. + """ + app_label = 'alter_alter_field_reloads_state_on_fk_target_changes' + project_state = self.apply_operations(app_label, ProjectState(), operations=[ + migrations.CreateModel('Rider', fields=[ + ('id', models.CharField(primary_key=True, max_length=100)), + ]), + migrations.CreateModel('Pony', fields=[ + ('id', models.CharField(primary_key=True, max_length=100)), + ('rider', models.ForeignKey('%s.Rider' % app_label, models.CASCADE)), + ]), + migrations.CreateModel('PonyRider', fields=[ + ('id', models.AutoField(primary_key=True)), + ('pony', models.ForeignKey('%s.Pony' % app_label, models.CASCADE)), + ]), + ]) + project_state = self.apply_operations(app_label, project_state, operations=[ + migrations.AlterField('Rider', 'id', models.CharField(primary_key=True, max_length=99)), + migrations.AlterField('Pony', 'id', models.CharField(primary_key=True, max_length=99)), + ]) + + def test_alter_field_reloads_state_on_fk_with_to_field_target_changes(self): + """ + If AlterField doesn't reload state appropriately, the second AlterField + crashes on MySQL due to not dropping the PonyRider.pony foreign key + constraint before modifying the column. + """ + app_label = 'alter_alter_field_reloads_state_on_fk_with_to_field_target_changes' + project_state = self.apply_operations(app_label, ProjectState(), operations=[ + migrations.CreateModel('Rider', fields=[ + ('id', models.CharField(primary_key=True, max_length=100)), + ('slug', models.CharField(unique=True, max_length=100)), + ]), + migrations.CreateModel('Pony', fields=[ + ('id', models.CharField(primary_key=True, max_length=100)), + ('rider', models.ForeignKey('%s.Rider' % app_label, models.CASCADE, to_field='slug')), + ('slug', models.CharField(unique=True, max_length=100)), + ]), + migrations.CreateModel('PonyRider', fields=[ + ('id', models.AutoField(primary_key=True)), + ('pony', models.ForeignKey('%s.Pony' % app_label, models.CASCADE, to_field='slug')), + ]), + ]) + project_state = self.apply_operations(app_label, project_state, operations=[ + migrations.AlterField('Rider', 'slug', models.CharField(unique=True, max_length=99)), + migrations.AlterField('Pony', 'slug', models.CharField(unique=True, max_length=99)), + ]) + + def test_rename_field_reloads_state_on_fk_target_changes(self): + """ + If RenameField doesn't reload state appropriately, the AlterField + crashes on MySQL due to not dropping the PonyRider.pony foreign key + constraint before modifying the column. + """ + app_label = 'alter_rename_field_reloads_state_on_fk_target_changes' + project_state = self.apply_operations(app_label, ProjectState(), operations=[ + migrations.CreateModel('Rider', fields=[ + ('id', models.CharField(primary_key=True, max_length=100)), + ]), + migrations.CreateModel('Pony', fields=[ + ('id', models.CharField(primary_key=True, max_length=100)), + ('rider', models.ForeignKey('%s.Rider' % app_label, models.CASCADE)), + ]), + migrations.CreateModel('PonyRider', fields=[ + ('id', models.AutoField(primary_key=True)), + ('pony', models.ForeignKey('%s.Pony' % app_label, models.CASCADE)), + ]), + ]) + project_state = self.apply_operations(app_label, project_state, operations=[ + migrations.RenameField('Rider', 'id', 'id2'), + migrations.AlterField('Pony', 'id', models.CharField(primary_key=True, max_length=99)), + ]) + def test_rename_field(self): """ Tests the RenameField operation. |
