#10626 closed (duplicate)
Default model ordering affects annotation query
| Reported by: | kmassey | Owned by: | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 1.1-beta |
| Severity: | Keywords: | values annotate ordering | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Example models without default orderings:
class Author(models.Model):
id = models.IntegerField(primary_key=True,
help_text='Uniquely identifies an author.')
name= models.CharField(max_length=200,
help_text="Author's first name.")
class Book(models.Model):
id = models.IntegerField(primary_key=True,
help_text='Uniquely identifies a book.')
title = models.CharField(max_length=200,
help_text='The title of this book.')
author = models.ForeignKey(Author, db_column='author_id',
help_text='The author of this book.')
price = models.FloatField(
help_text='Price of the book.')
inventory = models.IntegerField(
help_text='Copies of book in the store.')
Use values() and annotate() to determine the number of books at each price. This works as I expected:
>>> q = Book.objects.values('price').annotate(Count('price'))
>>> list(q)
[{'price': 7.9900000000000002, 'price__count': 2}, {'price': 9.9900000000000002, 'price__count': 1}]
Now add default orderings to the models:
class Author(models.Model):
id = models.IntegerField(primary_key=True,
help_text='Uniquely identifies an author.')
name= models.CharField(max_length=200,
help_text="Author's first name.")
class Meta:
ordering = ['id']
class Book(models.Model):
id = models.IntegerField(primary_key=True,
help_text='Uniquely identifies a book.')
title = models.CharField(max_length=200,
help_text='The title of this book.')
author = models.ForeignKey(Author, db_column='author_id',
help_text='The author of this book.')
price = models.FloatField(
help_text='Price of the book.')
inventory = models.IntegerField(
help_text='Copies of book in the store.')
class Meta:
ordering = ['id']
And repeat the query:
>>> q = Book.objects.values('price').annotate(Count('price'))
>>> list(q)
[{'price': 9.9900000000000002, 'price__count': 1}, {'price': 7.9900000000000002, 'price__count': 1}, {'price': 7.9900000000000002, 'price__count': 1}]
This isn't what I expected. It took me a while to make the connection between the model default ordering and the behavior of the annotation query. Once I saw it, the fix was easy:
>>> q = Book.objects.values('price').annotate(Count('price')).order_by()
>>> list(q)
[{'price': 7.9900000000000002, 'price__count': 2}, {'price': 9.9900000000000002, 'price__count': 1}]
I'm not sure if this should be a bug per se. If not, perhaps it could be noted in the aggregation documentation.
Thanks,
Kevin
Change History (3)
comment:1 by , 17 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
comment:3 by , 13 years ago
| Component: | ORM aggregation → Database layer (models, ORM) |
|---|
Note:
See TracTickets
for help on using tickets.
This is a dupe of #10574.