[Django] #31691: django.contrib.postgres.aggregates.JSONBAgg does not support ordering

252 views
Skip to first unread message

Django

unread,
Jun 11, 2020, 11:18:59 AM6/11/20
to django-...@googlegroups.com
#31691: django.contrib.postgres.aggregates.JSONBAgg does not support ordering
-------------------------------------+-------------------------------------
Reporter: john- | Owner: nobody
parton |
Type: New | Status: new
feature |
Component: Database | Version: 3.0
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Here's a contrived example:

{{{#!python
class Author(models.Model):
name = models.CharField(max_length=50)
alias = models.CharField(max_length=50, null=True, blank=True)
age = models.PositiveSmallIntegerField(default=30)


class Article(models.Model):
authors = models.ManyToManyField(Author, related_name='articles')
title = models.CharField(max_length=50)


Article.objects.annotate(
authors_json=JSONBAgg(
Func(
Value('name'), 'name',
Value('alias'), 'alias',
ordering='age'
)
)
)
}}}

The ordering kwarg is ignored, but Postgres would have no problem
understanding the aggregate with an ORDER BY clause

In my code I did the following

{{{#!python
class OrderableJSONBAgg(OrderableAggMixin, JSONBAgg)
pass


from myapp.aggregates import OrderableJSONBAgg as JSONBAgg
}}}

I believe adding that mixin is all that would be required to add this
functionality.

--
Ticket URL: <https://code.djangoproject.com/ticket/31691>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jun 11, 2020, 11:19:40 AM6/11/20
to django-...@googlegroups.com
#31691: django.contrib.postgres.aggregates.JSONBAgg does not support ordering
-------------------------------------+-------------------------------------
Reporter: john-parton | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by john-parton:

Old description:

New description:

Here's a contrived example:

{{{#!python
class Author(models.Model):
name = models.CharField(max_length=50)
alias = models.CharField(max_length=50, null=True, blank=True)
age = models.PositiveSmallIntegerField(default=30)


class Article(models.Model):
authors = models.ManyToManyField(Author, related_name='articles')
title = models.CharField(max_length=50)


Article.objects.annotate(
authors_json=JSONBAgg(
Func(
Value('name'), 'name',
Value('alias'), 'alias',

function='jsonb_build_object'
),
ordering='age'
)
)
}}}

The ordering kwarg is ignored, but Postgres would have no problem
understanding the aggregate with an ORDER BY clause

In my code I did the following

{{{#!python
class OrderableJSONBAgg(OrderableAggMixin, JSONBAgg)
pass


from myapp.aggregates import OrderableJSONBAgg as JSONBAgg
}}}

I believe adding that mixin is all that would be required to add this
functionality.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/31691#comment:1>

Django

unread,
Jun 11, 2020, 12:17:45 PM6/11/20
to django-...@googlegroups.com
#31691: django.contrib.postgres.aggregates.JSONBAgg does not support ordering
-------------------------------------+-------------------------------------
Reporter: john-parton | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by john-parton:

Old description:

> Here's a contrived example:


>
> {{{#!python
> class Author(models.Model):
> name = models.CharField(max_length=50)
> alias = models.CharField(max_length=50, null=True, blank=True)
> age = models.PositiveSmallIntegerField(default=30)
>

> class Article(models.Model):
> authors = models.ManyToManyField(Author, related_name='articles')
> title = models.CharField(max_length=50)
>

> Article.objects.annotate(
> authors_json=JSONBAgg(
> Func(
> Value('name'), 'name',
> Value('alias'), 'alias',

> function='jsonb_build_object'
> ),
> ordering='age'

> )
> )
> }}}
>
> The ordering kwarg is ignored, but Postgres would have no problem
> understanding the aggregate with an ORDER BY clause
>
> In my code I did the following
>
> {{{#!python
> class OrderableJSONBAgg(OrderableAggMixin, JSONBAgg)
> pass
>

> from myapp.aggregates import OrderableJSONBAgg as JSONBAgg
> }}}
>
> I believe adding that mixin is all that would be required to add this
> functionality.

New description:

Here's a contrived example:

{{{#!python
class Author(models.Model):
name = models.CharField(max_length=50)
alias = models.CharField(max_length=50, null=True, blank=True)
age = models.PositiveSmallIntegerField(default=30)


class Article(models.Model):
authors = models.ManyToManyField(Author, related_name='articles')
title = models.CharField(max_length=50)


Article.objects.annotate(
authors_json=JSONBAgg(
Func(
Value('name'), 'name',
Value('alias'), 'alias',

function='jsonb_build_object'
),
ordering='age'

)
)
}}}

The ordering kwarg is ignored, but Postgres would have no problem
understanding the aggregate with an ORDER BY clause

In my code I did the following

{{{#!python
class OrderableJSONBAgg(OrderableAggMixin, Aggregate):
function = 'JSONB_AGG'
template = '%(function)s(%(expressions)s %(ordering)s)'
output_field = JSONField()

def convert_value(self, value, expression, connection):
if not value:
return []
return value


from myapp.aggregates import OrderableJSONBAgg as JSONBAgg
}}}

I believe adding that mixin is all that would be required to add this
functionality.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/31691#comment:2>

Django

unread,
Jun 11, 2020, 1:12:21 PM6/11/20
to django-...@googlegroups.com
#31691: django.contrib.postgres.aggregates.JSONBAgg does not support ordering
-------------------------------------+-------------------------------------
Reporter: john-parton | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by john-parton:

Old description:

> Here's a contrived example:


>
> {{{#!python
> class Author(models.Model):
> name = models.CharField(max_length=50)
> alias = models.CharField(max_length=50, null=True, blank=True)
> age = models.PositiveSmallIntegerField(default=30)
>

> class Article(models.Model):
> authors = models.ManyToManyField(Author, related_name='articles')
> title = models.CharField(max_length=50)
>

> Article.objects.annotate(
> authors_json=JSONBAgg(
> Func(
> Value('name'), 'name',
> Value('alias'), 'alias',

> function='jsonb_build_object'
> ),
> ordering='age'

> )
> )
> }}}
>
> The ordering kwarg is ignored, but Postgres would have no problem
> understanding the aggregate with an ORDER BY clause
>
> In my code I did the following
>
> {{{#!python

> class OrderableJSONBAgg(OrderableAggMixin, Aggregate):
> function = 'JSONB_AGG'
> template = '%(function)s(%(expressions)s %(ordering)s)'
> output_field = JSONField()
>
> def convert_value(self, value, expression, connection):
> if not value:
> return []
> return value
>

> from myapp.aggregates import OrderableJSONBAgg as JSONBAgg


> }}}
>
> I believe adding that mixin is all that would be required to add this
> functionality.

New description:

Here's a contrived example:

{{{#!python
class Author(models.Model):
name = models.CharField(max_length=50)
alias = models.CharField(max_length=50, null=True, blank=True)
age = models.PositiveSmallIntegerField(default=30)


class Article(models.Model):
authors = models.ManyToManyField(Author, related_name='articles')
title = models.CharField(max_length=50)


Article.objects.annotate(
authors_json=JSONBAgg(
Func(
Value('name'), 'name',
Value('alias'), 'alias',

function='jsonb_build_object'
),
ordering='age'

)
)
}}}

The ordering kwarg is ignored, but Postgres would have no problem
understanding the aggregate with an ORDER BY clause

In my code I did the following

{{{#!python


class OrderableJSONBAgg(OrderableAggMixin, Aggregate):
function = 'JSONB_AGG'
template = '%(function)s(%(expressions)s %(ordering)s)'
output_field = JSONField()

def convert_value(self, value, expression, connection):
if not value:
return []
return value

from myapp.aggregates import OrderableJSONBAgg as JSONBAgg
}}}

I believe replacing the existing JSONBAgg with this implementation would
add the feature, with no backwards compat issues.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/31691#comment:3>

Django

unread,
Jun 11, 2020, 1:12:54 PM6/11/20
to django-...@googlegroups.com
#31691: django.contrib.postgres.aggregates.JSONBAgg does not support ordering
-------------------------------------+-------------------------------------
Reporter: john-parton | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by john-parton:

Old description:

> Here's a contrived example:


>
> {{{#!python
> class Author(models.Model):
> name = models.CharField(max_length=50)
> alias = models.CharField(max_length=50, null=True, blank=True)
> age = models.PositiveSmallIntegerField(default=30)
>

> class Article(models.Model):
> authors = models.ManyToManyField(Author, related_name='articles')
> title = models.CharField(max_length=50)
>

> Article.objects.annotate(
> authors_json=JSONBAgg(
> Func(
> Value('name'), 'name',
> Value('alias'), 'alias',

> function='jsonb_build_object'
> ),
> ordering='age'

> )
> )
> }}}
>
> The ordering kwarg is ignored, but Postgres would have no problem
> understanding the aggregate with an ORDER BY clause
>
> In my code I did the following
>
> {{{#!python

> class OrderableJSONBAgg(OrderableAggMixin, Aggregate):
> function = 'JSONB_AGG'
> template = '%(function)s(%(expressions)s %(ordering)s)'
> output_field = JSONField()
>
> def convert_value(self, value, expression, connection):
> if not value:
> return []
> return value
>

> from myapp.aggregates import OrderableJSONBAgg as JSONBAgg
> }}}
>


> I believe replacing the existing JSONBAgg with this implementation would
> add the feature, with no backwards compat issues.

New description:

Here's a contrived example:

{{{#!python
class Author(models.Model):
name = models.CharField(max_length=50)
alias = models.CharField(max_length=50, null=True, blank=True)
age = models.PositiveSmallIntegerField(default=30)


class Article(models.Model):
authors = models.ManyToManyField(Author, related_name='articles')
title = models.CharField(max_length=50)


Article.objects.annotate(
authors_json=JSONBAgg(
Func(
Value('name'), 'name',
Value('alias'), 'alias',

function='jsonb_build_object'
),
ordering='age'

)
)
}}}

The ordering kwarg is ignored, but Postgres would have no problem
understanding the aggregate with an ORDER BY clause

In my code I did the following

{{{#!python


class OrderableJSONBAgg(OrderableAggMixin, Aggregate):
function = 'JSONB_AGG'
template = '%(function)s(%(expressions)s %(ordering)s)'
output_field = JSONField()

def convert_value(self, value, expression, connection):
if not value:
return []
return value

from myapp.aggregates import OrderableJSONBAgg as JSONBAgg
}}}

I believe replacing the existing JSONBAgg with this implementation would


add the feature, with no backwards compat issues.

I would be happy to submit a pull request.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/31691#comment:4>

Django

unread,
Jun 12, 2020, 1:10:00 AM6/12/20
to django-...@googlegroups.com
#31691: Added ordering support to JSONBAgg.
----------------------------------+---------------------------------------
Reporter: john-parton | Owner: john-parton
Type: New feature | Status: assigned
Component: contrib.postgres | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+---------------------------------------
Changes (by john-parton):

* owner: nobody => john-parton
* status: new => assigned


Comment:

Sure. I think I can handle it.

--
Ticket URL: <https://code.djangoproject.com/ticket/31691#comment:6>

Django

unread,
Jun 12, 2020, 3:13:51 PM6/12/20
to django-...@googlegroups.com
#31691: Added ordering support to JSONBAgg.
----------------------------------+---------------------------------------
Reporter: john-parton | Owner: john-parton
Type: New feature | Status: assigned
Component: contrib.postgres | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+---------------------------------------
Changes (by Simon Charette):

* has_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/31691#comment:7>

Reply all
Reply to author
Forward
0 new messages