Fixed #30903 -- Fixed migrations crash on PostgreSQL when adding Index with opclasses and ordering.

This commit is contained in:
Hannes Ljungberg 2019-10-23 22:16:55 +02:00 committed by Mariusz Felisiak
parent 2a54ce72f9
commit fa5f3291e7
4 changed files with 38 additions and 5 deletions

View File

@ -340,6 +340,7 @@ answer newbie questions, and generally made Django that much better:
Gustavo Picon Gustavo Picon
hambaloney hambaloney
Hang Park <hangpark@kaist.ac.kr> Hang Park <hangpark@kaist.ac.kr>
Hannes Ljungberg <hannes.ljungberg@gmail.com>
Hannes Struß <x@hannesstruss.de> Hannes Struß <x@hannesstruss.de>
Hasan Ramezani <hasan.r67@gmail.com> Hasan Ramezani <hasan.r67@gmail.com>
Hawkeye Hawkeye

View File

@ -110,13 +110,14 @@ class IndexColumns(Columns):
def __str__(self): def __str__(self):
def col_str(column, idx): def col_str(column, idx):
try:
col = self.quote_name(column) + self.col_suffixes[idx]
except IndexError:
col = self.quote_name(column)
# Index.__init__() guarantees that self.opclasses is the same # Index.__init__() guarantees that self.opclasses is the same
# length as self.columns. # length as self.columns.
return '{} {}'.format(col, self.opclasses[idx]) col = '{} {}'.format(self.quote_name(column), self.opclasses[idx])
try:
col = '{} {}'.format(col, self.col_suffixes[idx])
except IndexError:
pass
return col
return ', '.join(col_str(column, idx) for idx, column in enumerate(self.columns)) return ', '.join(col_str(column, idx) for idx, column in enumerate(self.columns))

View File

@ -17,3 +17,7 @@ Bugfixes
* Prevented :option:`migrate --plan` from showing that ``RunPython`` operations * Prevented :option:`migrate --plan` from showing that ``RunPython`` operations
are irreversible when ``reverse_code`` callables don't have docstrings or are irreversible when ``reverse_code`` callables don't have docstrings or
when showing a forward migration plan (:ticket:`30870`). when showing a forward migration plan (:ticket:`30870`).
* Fixed migrations crash on PostgreSQL when adding an
:class:`~django.db.models.Index` with fields ordering and
:attr:`~.Index.opclasses` (:ticket:`30903`).

View File

@ -196,6 +196,33 @@ class SchemaIndexesPostgreSQLTests(TransactionTestCase):
cursor.execute(self.get_opclass_query % indexname) cursor.execute(self.get_opclass_query % indexname)
self.assertCountEqual(cursor.fetchall(), [('text_pattern_ops', indexname)]) self.assertCountEqual(cursor.fetchall(), [('text_pattern_ops', indexname)])
def test_ops_class_descending(self):
indexname = 'test_ops_class_ordered'
index = Index(
name=indexname,
fields=['-body'],
opclasses=['text_pattern_ops'],
)
with connection.schema_editor() as editor:
editor.add_index(IndexedArticle2, index)
with editor.connection.cursor() as cursor:
cursor.execute(self.get_opclass_query % indexname)
self.assertCountEqual(cursor.fetchall(), [('text_pattern_ops', indexname)])
def test_ops_class_descending_partial(self):
indexname = 'test_ops_class_ordered_partial'
index = Index(
name=indexname,
fields=['-body'],
opclasses=['text_pattern_ops'],
condition=Q(headline__contains='China'),
)
with connection.schema_editor() as editor:
editor.add_index(IndexedArticle2, index)
with editor.connection.cursor() as cursor:
cursor.execute(self.get_opclass_query % indexname)
self.assertCountEqual(cursor.fetchall(), [('text_pattern_ops', indexname)])
@skipUnless(connection.vendor == 'mysql', 'MySQL tests') @skipUnless(connection.vendor == 'mysql', 'MySQL tests')
class SchemaIndexesMySQLTests(TransactionTestCase): class SchemaIndexesMySQLTests(TransactionTestCase):