#python #django #django-queryset
Вопрос:
У меня есть простая модель:
class Expense(models.Model):
...
price = models.DecimalField(decimal_places=2, max_digits=6)
is_fixed = models.BooleanField(default=False)
Я пытаюсь выполнить простой запрос к group_by и агрегировать:
>>> from expenses.models import Expense
>>> from django.db.models import Sum
>>> qs = Expense.objects.values('is_fixed').annotate(total=Sum('price'))
Я ожидал, что qs
будет две записи:
>>> qs.count()
2
Но когда я оцениваю его, он возвращает девять!
>>> len(qs)
9
После оценки count
начинает возвращаться девять, а также:
>>> qs.count()
9
Чтобы илюстрировать еще больше:
>>> qs = Expense.objects.values('is_fixed').annotate(total=Sum('price'))
>>> qs.count() == len(qs)
False
>>> len(qs) == qs.count()
True
>>> qs = Expense.objects.values('is_fixed').annotate(total=Sum('price'))
>>> len(qs) == qs.count()
True
Я понятия не имею, что вызывает эту «аномалию». Как ты думаешь, что это может быть?
ОБНОВЛЕНИЕ: Вот некоторые данные, запрошенные bdbd:
[
{
"price": 9.11,
"category": "HOUSE",
"created_at": "14/08/2021",
"source": "BANK_SLIP",
"is_fixed": True
},
{
"price": 600.0,
"category": "GIFT",
"created_at": "09/08/2021",
"source": "BANK_TRANSFER",
"is_fixed": False
},
{
"price": 10.5,
"category": "FOOD",
"created_at": "08/08/2021",
"source": "SETTLE_UP",
"is_fixed": False
},
{
"price": 28.0,
"category": "GIFT",
"created_at": "08/08/2021",
"source": "SETTLE_UP",
"is_fixed": False
},
{
"price": 20.44,
"category": "SUPERMARKET",
"created_at": "07/08/2021",
"source": "SETTLE_UP",
"is_fixed": False
},
{
"price": 8.5,
"category": "SUPERMARKET",
"created_at": "06/08/2021",
"source": "CREDIT_CARD",
"is_fixed": False
},
{
"price": 726.0,
"category": "HOUSE",
"created_at": "04/08/2021",
"source": "BANK_SLIP",
"is_fixed": True
},
{
"price": 34.8,
"category": "HOUSE",
"created_at": "04/08/2021",
"source": "BANK_SLIP",
"is_fixed": True
},
{
"price": 43.97,
"category": "HOUSE",
"created_at": "04/08/2021",
"source": "MONEY",
"is_fixed": True
},
{
"price": 4.09,
"category": "SUPERMARKET",
"created_at": "04/08/2021",
"source": "CREDIT_CARD",
"is_fixed": False
},
{
"price": 168.0,
"category": "OTHER",
"created_at": "04/08/2021",
"source": "BANK_SLIP",
"is_fixed": False
},
{
"price": 23.4,
"category": "FOOD",
"created_at": "04/08/2021",
"source": "SETTLE_UP",
"is_fixed": False
},
{
"price": 169.0,
"category": "OTHER",
"created_at": "03/08/2021",
"source": "BANK_SLIP",
"is_fixed": False
},
{
"price": 9.81,
"category": "SUPERMARKET",
"created_at": "03/08/2021",
"source": "CREDIT_CARD",
"is_fixed": False
},
{
"price": 100.0,
"category": "RECREATION",
"created_at": "03/08/2021",
"source": "MONEY",
"is_fixed": False
},
{
"price": 10.0,
"category": "SUPERMARKET",
"created_at": "02/08/2021",
"source": "CREDIT_CARD",
"is_fixed": False
}
]
Комментарии:
1. Можете ли вы поделиться некоторыми данными?
2. @bdbd Я просто обновляю вопрос.
Ответ №1:
Проблема заключалась в том, что я поставил ordering
на Meta
:
class Meta:
ordering = ("-created_at",)
Установка правильного поля в предложении order_by устранила проблему:
>>> qs = Expense.objects.order_by("is_fixed").values("is_fixed").annotate(total=Sum("price"))
>>> len(qs) == qs.count()
True
>>> qs = Expense.objects.order_by("is_fixed").values("is_fixed").annotate(total=Sum("price"))
>>> qs.count() == len(qs)
True
Комментарии:
1. Интересно, почему порядок изменил бы количество записей в наборе запросов?
2. @JohnGordon В соответствии с документами django: «Аналогично, если вы используете запрос values() для ограничения выбранных столбцов, столбцы, используемые в любом заказе() (или заказе модели по умолчанию), все равно будут задействованы и могут повлиять на уникальность результатов». docs.djangoproject.com/en/3.2/ref/models/querysets