diff options
| author | Hannes Ljungberg <hannes.ljungberg@gmail.com> | 2021-02-06 20:45:54 +0100 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-02-23 20:19:53 +0100 |
| commit | 3aa545281e0c0f9fac93753e3769df9e0334dbaa (patch) | |
| tree | 454bec922a78df9ecfe6eab197e7750e8a5bafac /tests/postgres_tests/test_constraints.py | |
| parent | 19ce1d493ae7cbc1e704d338077b1f5f5e5769c9 (diff) | |
Fixed #30916 -- Added support for functional unique constraints.
Thanks Ian Foote and Mariusz Felisiak for reviews.
Diffstat (limited to 'tests/postgres_tests/test_constraints.py')
| -rw-r--r-- | tests/postgres_tests/test_constraints.py | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/tests/postgres_tests/test_constraints.py b/tests/postgres_tests/test_constraints.py index 80c2bb77b6..7915bb226e 100644 --- a/tests/postgres_tests/test_constraints.py +++ b/tests/postgres_tests/test_constraints.py @@ -1,6 +1,7 @@ import datetime from unittest import mock +from django.contrib.postgres.indexes import OpClass from django.db import ( IntegrityError, NotSupportedError, connection, transaction, ) @@ -8,8 +9,8 @@ from django.db.models import ( CheckConstraint, Deferrable, F, Func, IntegerField, Q, UniqueConstraint, ) from django.db.models.fields.json import KeyTextTransform -from django.db.models.functions import Cast, Left -from django.test import skipUnlessDBFeature +from django.db.models.functions import Cast, Left, Lower +from django.test import modify_settings, skipUnlessDBFeature from django.utils import timezone from . import PostgreSQLTestCase @@ -26,6 +27,7 @@ except ImportError: pass +@modify_settings(INSTALLED_APPS={'append': 'django.contrib.postgres'}) class SchemaTests(PostgreSQLTestCase): get_opclass_query = ''' SELECT opcname, c.relname FROM pg_opclass AS oc @@ -166,6 +168,33 @@ class SchemaTests(PostgreSQLTestCase): [('varchar_pattern_ops', constraint.name)], ) + @skipUnlessDBFeature('supports_expression_indexes') + def test_opclass_func(self): + constraint = UniqueConstraint( + OpClass(Lower('scene'), name='text_pattern_ops'), + name='test_opclass_func', + ) + with connection.schema_editor() as editor: + editor.add_constraint(Scene, constraint) + constraints = self.get_constraints(Scene._meta.db_table) + self.assertIs(constraints[constraint.name]['unique'], True) + self.assertIn(constraint.name, constraints) + with editor.connection.cursor() as cursor: + cursor.execute(self.get_opclass_query, [constraint.name]) + self.assertEqual( + cursor.fetchall(), + [('text_pattern_ops', constraint.name)], + ) + Scene.objects.create(scene='Scene 10', setting='The dark forest of Ewing') + with self.assertRaises(IntegrityError), transaction.atomic(): + Scene.objects.create(scene='ScEnE 10', setting="Sir Bedemir's Castle") + Scene.objects.create(scene='Scene 5', setting="Sir Bedemir's Castle") + # Drop the constraint. + with connection.schema_editor() as editor: + editor.remove_constraint(Scene, constraint) + self.assertNotIn(constraint.name, self.get_constraints(Scene._meta.db_table)) + Scene.objects.create(scene='ScEnE 10', setting="Sir Bedemir's Castle") + class ExclusionConstraintTests(PostgreSQLTestCase): def get_constraints(self, table): |
