Skip to content

Commit

Permalink
true solution for order by JSONBAgg result with Coalesce fix
Browse files Browse the repository at this point in the history
  • Loading branch information
xjlin0 committed May 9, 2024
1 parent 47edbda commit c86e8ce
Showing 1 changed file with 8 additions and 12 deletions.
20 changes: 8 additions & 12 deletions attendees/persons/services/attendee_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
from pathlib import Path
from partial_date import PartialDate
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.aggregates.general import ArrayAgg, StringAgg, JSONBAgg
from django.db.models import Case, F, Func, Q, When, CharField
from django.db.models.functions import Cast, Substr, Coalesce, JSONObject
from django.contrib.postgres.aggregates.general import StringAgg, JSONBAgg
from django.db.models import Case, F, Func, Q, When, CharField, JSONField
from django.db.models.functions import Cast, Substr, Coalesce
from django.db.models.expressions import OrderBy, Value
from django.http import Http404
from rest_framework.utils import json
Expand Down Expand Up @@ -186,11 +186,7 @@ def by_datagrid_params(
qs.select_related()
.prefetch_related()
.annotate(
attending_meet_slugs=Coalesce(ArrayAgg('attendings__meets__slug',
filter=Q(attendings__attendingmeet__finish__gte=now,
attendings__attendingmeet__is_removed=False),
distinct=True), []), # Sorting only since <@ for JSONBAgg doesn't work
attendingmeets=JSONBAgg(
attendingmeets=Coalesce(JSONBAgg( # Coalesce required or null/true/false will break sorting
Func(
Value('attendingmeet_id'), 'attendings__attendingmeet',
Value('meet_slug'), 'attendings__meets__slug',
Expand All @@ -201,7 +197,7 @@ def by_datagrid_params(
filter=Q(attendings__attendingmeet__finish__gte=now, attendings__attendingmeet__is_removed=False),
distinct=True,
default=[],
),
), Value('[]'), output_field=JSONField()),
folkcities=StringAgg('folks__places__address__locality__name',
filter=(Q(folks__places__finish__isnull=True) | Q(folks__places__finish__gte=now)) & Q(folks__places__is_removed=False),
delimiter=", ",
Expand All @@ -225,12 +221,12 @@ def orderby_parser(orderby_string, meets, current_user):
:param current_user:
:return: a List of sorter for order_by()
"""
meet_sorters = { # function="'[{\"meet_slug\":\"" + meet.slug + "\"}]'::jsonb <@ " doesn't sort for JSONBAgg
meet.slug: Func("attending_meet_slugs", function="'{}'=ANY".format(meet.slug))
meet_sorters = { # this sorter only needed since there're dynamic columns (slug is column name)
meet.slug: Func("attendingmeets", function="'[{\"meet_slug\":\"" + meet.slug + "\"}]'::jsonb <@ ")
for meet in Meet.objects.filter(
id__in=meets, assembly__division__organization=current_user.organization
)
} # this sorter only needed since there're dynamic columns (slug is column name)
}

orderby_list = (
[]
Expand Down

0 comments on commit c86e8ce

Please sign in to comment.