Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django ORM & hstore : counting unique values of a key

Having the following model:

from django_hstore import hstore
from django.db import models

class Item(VoteModel):
    data = hstore.DictionaryField(db_index=True)
    objects = hstore.HStoreManager()

Something like:

Item.objects.extra(select={"key": "content_item.data -> 'key'"}).aggregate(Count('key'))

doesn't work, cf. Using .aggregate() on a value introduced using .extra(select={...}) in a Django Query? and https://code.djangoproject.com/ticket/11671.

The raw SQL which works is the following:

SELECT content_item.data -> 'key' AS key, count(*)  FROM content_item GROUP BY key;                                                                               
   key     | count 
-----------+-------
 value1    |   223
 value2    |    28
 value3    |    31
(3 rows)

How can I get hte same results through Django's ORM ?

FYI:

Item.objects.extra(select={"key": "content_item.data -> 'key'"})

translates to:

SELECT (content_item.data -> 'key') AS "key", "content_item"."id", "content_item"."data" FROM "content_item"
like image 854
Maxime R. Avatar asked Sep 21 '12 00:09

Maxime R.


People also ask

What is an ORM in Django?

ORM stands for Object Relational Mapper. The main goal of ORM is to send data between a database and models in an application. It maps a relation between the database and a model. So, ORM maps object attributes to fields of a table.

Does Django have ORM?

The Django web framework includes a default object-relational mapping layer (ORM) that can be used to interact with application data from various relational databases such as SQLite, PostgreSQL and MySQL.

Is Django ORM good?

The Django ORM is a very powerful tool, and one of the great attractions of Django. It makes writing simple queries trivial, and does a great job of abstracting away the database layer in your application. And sometimes, you shouldn't use it.

Why Django ORM is lazy?

Django's ORM allows you to interact with a relational database in a way that feels natural for the Object-Oriented Python programming language. The code is precise code and semantically clear. Django uses lazy loading to only load the author if you need it. This is great, but can lead to an explosion of queries.


1 Answers

Have you tried with values and order_by?

Item.objects.extra(
    select=dict(key = "content_item.data -> 'key'")
).values('key').order_by('key').annotate(total=Count('key'))

Something like this works for me in PostgreSQL and Django 1.4.

like image 77
Paulo Scardine Avatar answered Sep 21 '22 04:09

Paulo Scardine