Fixed #32169 -- Added distinct support to JSONBAgg.

This commit is contained in:
Artur Beltsov 2020-11-04 16:30:47 +05:00 committed by Mariusz Felisiak
parent c36075ac1d
commit 18c8ced81e
4 changed files with 25 additions and 2 deletions

View File

@ -43,7 +43,8 @@ class BoolOr(Aggregate):
class JSONBAgg(OrderableAggMixin, Aggregate): class JSONBAgg(OrderableAggMixin, Aggregate):
function = 'JSONB_AGG' function = 'JSONB_AGG'
template = '%(function)s(%(expressions)s %(ordering)s)' template = '%(function)s(%(distinct)s%(expressions)s %(ordering)s)'
allow_distinct = True
output_field = JSONField() output_field = JSONField()
def convert_value(self, value, expression, connection): def convert_value(self, value, expression, connection):

View File

@ -114,10 +114,17 @@ General-purpose aggregation functions
``JSONBAgg`` ``JSONBAgg``
------------ ------------
.. class:: JSONBAgg(expressions, filter=None, ordering=(), **extra) .. class:: JSONBAgg(expressions, distinct=False, filter=None, ordering=(), **extra)
Returns the input values as a ``JSON`` array. Returns the input values as a ``JSON`` array.
.. attribute:: distinct
.. versionadded:: 3.2
An optional boolean argument that determines if array values will be
distinct. Defaults to ``False``.
.. attribute:: ordering .. attribute:: ordering
.. versionadded:: 3.2 .. versionadded:: 3.2

View File

@ -131,6 +131,9 @@ Minor features
* The new :attr:`.JSONBAgg.ordering` attribute determines the ordering of the * The new :attr:`.JSONBAgg.ordering` attribute determines the ordering of the
aggregated elements. aggregated elements.
* The new :attr:`.JSONBAgg.distinct` attribute determines if aggregated values
will be distinct.
* The :class:`~django.contrib.postgres.operations.CreateExtension` operation * The :class:`~django.contrib.postgres.operations.CreateExtension` operation
now checks that the extension already exists in the database and skips the now checks that the extension already exists in the database and skips the
migration if so. migration if so.

View File

@ -428,6 +428,18 @@ class TestAggregateDistinct(PostgreSQLTestCase):
values = AggregateTestModel.objects.aggregate(arrayagg=ArrayAgg('char_field', distinct=True)) values = AggregateTestModel.objects.aggregate(arrayagg=ArrayAgg('char_field', distinct=True))
self.assertEqual(sorted(values['arrayagg']), ['Bar', 'Foo']) self.assertEqual(sorted(values['arrayagg']), ['Bar', 'Foo'])
def test_json_agg_distinct_false(self):
values = AggregateTestModel.objects.aggregate(
jsonagg=JSONBAgg('char_field', distinct=False),
)
self.assertEqual(sorted(values['jsonagg']), ['Bar', 'Foo', 'Foo'])
def test_json_agg_distinct_true(self):
values = AggregateTestModel.objects.aggregate(
jsonagg=JSONBAgg('char_field', distinct=True),
)
self.assertEqual(sorted(values['jsonagg']), ['Bar', 'Foo'])
class TestStatisticsAggregate(PostgreSQLTestCase): class TestStatisticsAggregate(PostgreSQLTestCase):
@classmethod @classmethod