From 4d99375b46ad03fa4b4795319973046f438328c8 Mon Sep 17 00:00:00 2001 From: Hannes Ljungberg Date: Wed, 17 Feb 2021 10:46:40 +0100 Subject: [PATCH] Fixed #32453 -- Added introspection of unique constraint field ordering on SQLite. Co-authored-by: Mariusz Felisiak --- django/db/backends/sqlite3/introspection.py | 2 +- tests/introspection/models.py | 15 +++++++++++++++ tests/introspection/tests.py | 15 ++++++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py index 8c1d4582ab..f109b5d5ee 100644 --- a/django/db/backends/sqlite3/introspection.py +++ b/django/db/backends/sqlite3/introspection.py @@ -413,7 +413,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): } constraints[index]['columns'].append(column) # Add type and column orders for indexes - if constraints[index]['index'] and not constraints[index]['unique']: + if constraints[index]['index']: # SQLite doesn't support any index type other than b-tree constraints[index]['type'] = Index.suffix orders = self._get_index_columns_orders(sql) diff --git a/tests/introspection/models.py b/tests/introspection/models.py index 72881cf43c..30a7a8b3ee 100644 --- a/tests/introspection/models.py +++ b/tests/introspection/models.py @@ -80,3 +80,18 @@ class CheckConstraintModel(models.Model): constraints = [ models.CheckConstraint(name='up_votes_gte_0_check', check=models.Q(up_votes__gte=0)), ] + + +class UniqueConstraintConditionModel(models.Model): + name = models.CharField(max_length=255) + color = models.CharField(max_length=32, null=True) + + class Meta: + required_db_features = {'supports_partial_indexes'} + constraints = [ + models.UniqueConstraint( + fields=['name'], + name='cond_name_without_color_uniq', + condition=models.Q(color__isnull=True), + ), + ] diff --git a/tests/introspection/tests.py b/tests/introspection/tests.py index 82a661a83d..bd5d7c942a 100644 --- a/tests/introspection/tests.py +++ b/tests/introspection/tests.py @@ -6,7 +6,7 @@ from django.test import TransactionTestCase, skipUnlessDBFeature from .models import ( Article, ArticleReporter, CheckConstraintModel, City, Comment, Country, - District, Reporter, + District, Reporter, UniqueConstraintConditionModel, ) @@ -221,6 +221,19 @@ class IntrospectionTests(TransactionTestCase): indexes_verified += 1 self.assertEqual(indexes_verified, len(expected_columns)) + @skipUnlessDBFeature('supports_index_column_ordering', 'supports_partial_indexes') + def test_get_constraints_unique_indexes_orders(self): + with connection.cursor() as cursor: + constraints = connection.introspection.get_constraints( + cursor, + UniqueConstraintConditionModel._meta.db_table, + ) + self.assertIn('cond_name_without_color_uniq', constraints) + constraint = constraints['cond_name_without_color_uniq'] + self.assertIs(constraint['unique'], True) + self.assertEqual(constraint['columns'], ['name']) + self.assertEqual(constraint['orders'], ['ASC']) + def test_get_constraints(self): def assertDetails(details, cols, primary_key=False, unique=False, index=False, check=False, foreign_key=None): # Different backends have different values for same constraints: