Выполнение агрегатной функции на объединении Django queryset с переименованными полями приводит к ошибке django.db.utils.DatabaseError
Я использую Django 3.2
Я пытаюсь создать запрос, который запрашивает две различные модели и делает следующее:
- переименовывает возвращаемые столбцы (чтобы запросы можно было "объединить" вместе )
- "объединяет" два набора запросов (после переименования столбцов с помощью
annotate
) - пытается запустить агрегатную функцию
Sum
на объединении (вот где она глючит).
Это упрощенная версия моей кодовой базы:
Модели
class EventCategory(models.Model):
name = models.CharField(max_length=16)
class Event(models.Model):
name = models.CharField(max_length=32)
category = models.ForeignKey(EventCategory, on_delete=models.CASCADE)
class Tournament(models.Model):
name = models.CharField(max_length=32)
category = models.ForeignKey(EventCategory, on_delete=models.CASCADE)
prize_money = models.IntegerField()
class TournamentAward(models.Model):
awardee = models.ForeignKey(setting.AUTH_USER_MODEL, on_delete=models.CASCADE)
tournament = models.ForeignKey(Tournament, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class Game(models.Model):
player = models.ForeignKey(setting.AUTH_USER_MODEL, on_delete=models.CASCADE)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
payment = models.SmallPositiveInteger()
created_at = models.DateTimeField(auto_now_add=True)
Запросы
payment_earned_today = Game.objects.filter(
player=user,
created_at__year=year,
created_at__month=month,
created_at__day=day
).annotate(category=models.F('event__category'))\
.only('category','payment')
tournament_prize_today = TournamentAward.objects.filter(
awardee=user,
created_at__year=year,
created_at__month=month,
created_at__day=day
).select_related('tournament__category')\
.annotate(category=models.F('tournament__category'))\
.annotate(payment=models.F('tournament__prize_money'))\
.only('category','payment')
# Union the two querysets ...
union_queryset = payment_earned_today.union( tournament_prize_today )
results = union_queryset.aggregate(total=models.Sum('payment'))
В строке, когда я пытаюсь вычислить общую сумму, я получаю следующую ошибку:
django.db.utils.DatabaseError: ORDER BY не разрешен в подзапросах составных операторов
Как я могу объединить две модели и вычислить агрегатную функцию на объединении?
сначала:
вам не нужно переименовывать поля.
filter_query = Q(created_at__year=year,created_at__month=month,created_at__day=day)
payment_earned_today = Game.objects.filter(player=user, filter_query).values('event__category'. 'payment')
в секунду:
вы можете установить order_by
перед агрегатом.
queryset.query.order_by=None
на третьем:
Почему вы не идете от category
?
event_query = Q(event__game__created_at__year=year, event__game__created_at__month=month, event__game__created_at__day=day, event__game__player=user)
tournament_query = Q(tournament__tournamentaward__created_at__year=year, tournament__tournamentaward__created_at__month=month, tournament__tournamentaward__created_at__day=day, tournament__tournamentaward__awardee=user)
all_category = EventCategory.ojects.filter(event_query | tournament_query)
Я не понимаю, является ли ошибка в вашей последней строке ядра или нет:
results
является множественным числом, но у вас есть aggregate(sum)
, это дает вам только один результат. Поэтому:
all_category_with_summ_in_day_for_user = all_category.annotate(Sum('tournament__prize_money'), Sum('event__game__payment'))
# or
summs_for_all_category_in_day_for_user= all_category.aggregate(Sum('tournament__prize_money'), Sum('event__game__payment'))