Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Return array in subquery

I have a model Application that has many Judge objects assigned to it via ForeignKey. Each Judge will grade the Application. I want to return a list of Applications in a QuerySet along with an array of each of the score values. Here's how I"m trying to accomplish that:

total_scores = Subquery(
    Judge.objects
    .filter(
        application=OuterRef('pk')
    )
    .values_list(
        'total_score',
        flat=True
    )
)

applications = Application.objects \
    .annotate(
        score_array=total_scores
    )

But I get this error:

more than one row returned by a subquery used as an expression

The values_list should return an array of values, so i'm not sure why multiple rows are being returned from my subquery. Any pointers? Thanks.

like image 916
AlxVallejo Avatar asked Jun 29 '18 13:06

AlxVallejo


1 Answers

First of all, arrays are typically not a well implemented structure in most (all) databases, so I would advice to keep away from it as much as possible. Especially since it structures row-wise data into a single column, which makes it harder to perform JOINs, etc.

But if you really want this, you can use the ArrayAgg aggregate function. This is however a PostgreSQL specific function, thus you lose some freedom to pick another database system.

You can then probably obtain such result with:

from django.contrib.postgres.aggregates import ArrayAgg

Application.objects.annotate(
    score_array=ArrayAgg('judge__total_score')
)

So this does not require a SubQuery.

like image 129
Willem Van Onsem Avatar answered Nov 07 '22 08:11

Willem Van Onsem