У меня следующие три таблицы определены.Избегайте декартова продукта с Django
class Operator(models.Model):
DisplayName = models.CharField(max_length=64)
class Meta:
app_label = "Experiment"
db_table = "EXPERIMENT_OPERATOR"
class OperatorSummary(models.Model):
Operator = models.ForeignKey(Operator, related_name="TransactionSummary")
TransactionCount = models.IntegerField()
TransactionValue = models.DecimalField(max_digits=18, decimal_places=2)
StartTime = models.DateTimeField(default=timezone.now())
class Meta:
app_label = "Experiment"
db_table = "EXPERIMENT_OPERATORSUMMARY"
class OperatorAlerts(models.Model):
Operator = models.ForeignKey(Operator, related_name="AlertSummary")
AlertScore = models.IntegerField()
AlertCount = models.IntegerField()
StartTime = models.DateTimeField(default=timezone.now())
class Meta:
app_label = "Experiment"
db_table = "EXPERIMENT_OPERATORALERTS"
для оператора, я хотел бы, чтобы получить AlertScore
и TransactionCount
для заданного диапазона дат. Запрос я использую выглядит следующим образом:
tz = timezone.get_default_timezone()
vs = Operator.objects.filter(DisplayName="Jimmy",
TransactionSummary__StartTime__gte=tz.localize(datetime(year=2013, month=10, day=1)),
AlertSummary__StartTime__gte=tz.localize(datetime(year=2013, month=10, day=1)))\
.annotate(TotalTransactions=Sum("TransactionSummary__TransactionCount"),
TotalAlerts=Sum("AlertSummary__AlertScore"))\
.values("DisplayName", "TransactionSummary__TransactionCount", "AlertSummary__AlertScore")
Этот запрос выполняет декартово произведение и возвращает все строки в OperatorAlerts и OperatorSummary таблицы, которые соответствуют запросу. Это то, что она возвращает:
{'AlertSummary__AlertScore': 20, 'DisplayName': u'Jimmy', 'TransactionSummary__TransactionCount': 10}
{'AlertSummary__AlertScore': 44, 'DisplayName': u'Jimmy', 'TransactionSummary__TransactionCount': 10}
{'AlertSummary__AlertScore': 543, 'DisplayName': u'Jimmy', 'TransactionSummary__TransactionCount': 10}
{'AlertSummary__AlertScore': 20, 'DisplayName': u'Jimmy', 'TransactionSummary__TransactionCount': 22}
{'AlertSummary__AlertScore': 44, 'DisplayName': u'Jimmy', 'TransactionSummary__TransactionCount': 22}
{'AlertSummary__AlertScore': 543, 'DisplayName': u'Jimmy', 'TransactionSummary__TransactionCount': 22}
{'AlertSummary__AlertScore': 20, 'DisplayName': u'Jimmy', 'TransactionSummary__TransactionCount': 234}
{'AlertSummary__AlertScore': 44, 'DisplayName': u'Jimmy', 'TransactionSummary__TransactionCount': 234}
{'AlertSummary__AlertScore': 543, 'DisplayName': u'Jimmy', 'TransactionSummary__TransactionCount': 234}
Я хотел бы, чтобы это исправить, так что я получаю следующий результат:
{'AlertSummary__AlertScore': 607, 'DisplayName': u'Jimmy', 'TransactionSummary__TransactionCount': 266}
Все результаты рухнуло в одну строку, где AlertScore и TransactionCount суммируются ,
Возможно ли это? Я всегда могу вернуться к созданию отдельного запроса для OperatorAlerts и OperatorSummary, а затем итерации по набору результатов в Python для получения результатов, которые я хочу, или для вызова .aggregate
, но я уверен, что должен быть лучший способ?
Спасибо за очень полезный ответ. Вы правы, что я хотел бы запросить сразу несколько операторов. Тем не менее, я 'annotate' все еще то, что мне нужно, поскольку я бы хотел, чтобы« TotalTransactions »и« TotalAlerts »были для каждого пользователя, а не для всех пользователей. – CadentOrange
Я согласен, это именно то, что я имел в виду. Я думаю, что предложение было немного запутанным, потому что я использовал неправильную грамматическую форму. Я исправил это сейчас. –