#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 , 16 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
comment:3 by , 12 years ago
Component: | ORM aggregation → Database layer (models, ORM) |
---|
Note:
See TracTickets
for help on using tickets.
This is a dupe of #10574.