mirror of
https://github.com/django/django.git
synced 2025-08-04 02:48:35 +00:00
Fixed #30916 -- Added support for functional unique constraints.
Thanks Ian Foote and Mariusz Felisiak for reviews.
This commit is contained in:
parent
19ce1d493a
commit
3aa545281e
15 changed files with 779 additions and 38 deletions
|
@ -2562,6 +2562,99 @@ class OperationTests(OperationTestBase):
|
|||
'name': 'covering_pink_constraint_rm',
|
||||
})
|
||||
|
||||
def test_add_func_unique_constraint(self):
|
||||
app_label = 'test_adfuncuc'
|
||||
constraint_name = f'{app_label}_pony_abs_uq'
|
||||
table_name = f'{app_label}_pony'
|
||||
project_state = self.set_up_test_model(app_label)
|
||||
constraint = models.UniqueConstraint(Abs('weight'), name=constraint_name)
|
||||
operation = migrations.AddConstraint('Pony', constraint)
|
||||
self.assertEqual(
|
||||
operation.describe(),
|
||||
'Create constraint test_adfuncuc_pony_abs_uq on model Pony',
|
||||
)
|
||||
self.assertEqual(
|
||||
operation.migration_name_fragment,
|
||||
'pony_test_adfuncuc_pony_abs_uq',
|
||||
)
|
||||
new_state = project_state.clone()
|
||||
operation.state_forwards(app_label, new_state)
|
||||
self.assertEqual(len(new_state.models[app_label, 'pony'].options['constraints']), 1)
|
||||
self.assertIndexNameNotExists(table_name, constraint_name)
|
||||
# Add constraint.
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_forwards(app_label, editor, project_state, new_state)
|
||||
Pony = new_state.apps.get_model(app_label, 'Pony')
|
||||
Pony.objects.create(weight=4.0)
|
||||
if connection.features.supports_expression_indexes:
|
||||
self.assertIndexNameExists(table_name, constraint_name)
|
||||
with self.assertRaises(IntegrityError):
|
||||
Pony.objects.create(weight=-4.0)
|
||||
else:
|
||||
self.assertIndexNameNotExists(table_name, constraint_name)
|
||||
Pony.objects.create(weight=-4.0)
|
||||
# Reversal.
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_backwards(app_label, editor, new_state, project_state)
|
||||
self.assertIndexNameNotExists(table_name, constraint_name)
|
||||
# Constraint doesn't work.
|
||||
Pony.objects.create(weight=-4.0)
|
||||
# Deconstruction.
|
||||
definition = operation.deconstruct()
|
||||
self.assertEqual(definition[0], 'AddConstraint')
|
||||
self.assertEqual(definition[1], [])
|
||||
self.assertEqual(
|
||||
definition[2],
|
||||
{'model_name': 'Pony', 'constraint': constraint},
|
||||
)
|
||||
|
||||
def test_remove_func_unique_constraint(self):
|
||||
app_label = 'test_rmfuncuc'
|
||||
constraint_name = f'{app_label}_pony_abs_uq'
|
||||
table_name = f'{app_label}_pony'
|
||||
project_state = self.set_up_test_model(app_label, constraints=[
|
||||
models.UniqueConstraint(Abs('weight'), name=constraint_name),
|
||||
])
|
||||
self.assertTableExists(table_name)
|
||||
if connection.features.supports_expression_indexes:
|
||||
self.assertIndexNameExists(table_name, constraint_name)
|
||||
operation = migrations.RemoveConstraint('Pony', constraint_name)
|
||||
self.assertEqual(
|
||||
operation.describe(),
|
||||
'Remove constraint test_rmfuncuc_pony_abs_uq from model Pony',
|
||||
)
|
||||
self.assertEqual(
|
||||
operation.migration_name_fragment,
|
||||
'remove_pony_test_rmfuncuc_pony_abs_uq',
|
||||
)
|
||||
new_state = project_state.clone()
|
||||
operation.state_forwards(app_label, new_state)
|
||||
self.assertEqual(len(new_state.models[app_label, 'pony'].options['constraints']), 0)
|
||||
Pony = new_state.apps.get_model(app_label, 'Pony')
|
||||
self.assertEqual(len(Pony._meta.constraints), 0)
|
||||
# Remove constraint.
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_forwards(app_label, editor, project_state, new_state)
|
||||
self.assertIndexNameNotExists(table_name, constraint_name)
|
||||
# Constraint doesn't work.
|
||||
Pony.objects.create(pink=1, weight=4.0)
|
||||
Pony.objects.create(pink=1, weight=-4.0).delete()
|
||||
# Reversal.
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_backwards(app_label, editor, new_state, project_state)
|
||||
if connection.features.supports_expression_indexes:
|
||||
self.assertIndexNameExists(table_name, constraint_name)
|
||||
with self.assertRaises(IntegrityError):
|
||||
Pony.objects.create(weight=-4.0)
|
||||
else:
|
||||
self.assertIndexNameNotExists(table_name, constraint_name)
|
||||
Pony.objects.create(weight=-4.0)
|
||||
# Deconstruction.
|
||||
definition = operation.deconstruct()
|
||||
self.assertEqual(definition[0], 'RemoveConstraint')
|
||||
self.assertEqual(definition[1], [])
|
||||
self.assertEqual(definition[2], {'model_name': 'Pony', 'name': constraint_name})
|
||||
|
||||
def test_alter_model_options(self):
|
||||
"""
|
||||
Tests the AlterModelOptions operation.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue