Aggregating records
Suppose you have some users and want to get a list of them along with the countof tweets in each.
- query = (User
- .select(User, fn.Count(Tweet.id).alias('count'))
- .join(Tweet, JOIN.LEFT_OUTER)
- .group_by(User))
The resulting query will return User objects with all their normal attributesplus an additional attribute count which will contain the count of tweets foreach user. We use a left outer join to include users who have no tweets.
Let’s assume you have a tagging application and want to find tags that have acertain number of related objects. For this example we’ll use some differentmodels in a many-to-many configuration:
- class Photo(Model):
- image = CharField()
- class Tag(Model):
- name = CharField()
- class PhotoTag(Model):
- photo = ForeignKeyField(Photo)
- tag = ForeignKeyField(Tag)
Now say we want to find tags that have at least 5 photos associated with them:
- query = (Tag
- .select()
- .join(PhotoTag)
- .join(Photo)
- .group_by(Tag)
- .having(fn.Count(Photo.id) > 5))
This query is equivalent to the following SQL:
- SELECT t1."id", t1."name"
- FROM "tag" AS t1
- INNER JOIN "phototag" AS t2 ON t1."id" = t2."tag_id"
- INNER JOIN "photo" AS t3 ON t2."photo_id" = t3."id"
- GROUP BY t1."id", t1."name"
- HAVING Count(t3."id") > 5
Suppose we want to grab the associated count and store it on the tag:
- query = (Tag
- .select(Tag, fn.Count(Photo.id).alias('count'))
- .join(PhotoTag)
- .join(Photo)
- .group_by(Tag)
- .having(fn.Count(Photo.id) > 5))