Reputation: 1245
With the following simplified classes and tables
tags = db.Table(
"tags",
db.Column("tag_id", db.Integer, db.ForeignKey("tag.id")),
db.Column("post_version_id", db.Integer, db.ForeignKey("post_version.id"))
)
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
class PostVersion(db.Model):
id = db.Column(db.Integer, primary_key=True)
current = db.Column(db.Boolean, default=False, index=True)
I am trying to issue a call for all Tag
's ordered by the number of PostVersion
's that are both connected via tags
and possess the value current=True
.
I have developed the following query:
db.session.query(Tag,
db.func.count(PostVersion.id).label("total")
).outerjoin(tags
).outerjoin(PostVersion,
and_(PostVersion.id==tags.c.post_version_id,
PostVersion.current==True)
).group(Tag).order_by("total DESC").all()
Which yields the following (correct) results:
[(<Tag 8: original>, 136),
(<Tag 16: constance-garnett>, 136),
(<Tag 3: explanation>, 3),
(<Tag 2: definition>, 1),
(<Tag 14: translation>, 1),
(<Tag 1: biblical>, 0),
(<Tag 4: homage>, 0),
(<Tag 5: intertextuality>, 0),
(<Tag 6: meter>, 0),
(<Tag 7: mythology>, 0),
(<Tag 9: political>, 0),
(<Tag 10: cultural>, 0),
(<Tag 11: reference>, 0),
(<Tag 12: shakespeare>, 0),
(<Tag 13: technical-issues>, 0),
(<Tag 15: context>, 0)]
Except that I have to do additional modifications to the results in order to suppress the tuple-based output which includes the results of db.func.count(PostVersion.id).label("total")
and I am entirely unsure of how to rewrite the query to suppress just that.
Upvotes: 0
Views: 32
Reputation: 52929
The solution is simple: move the count expression to the ORDER BY clause:
db.session.query(Tag).\
outerjoin(tags).\
outerjoin(PostVersion,
and_(PostVersion.id==tags.c.post_version_id,
PostVersion.current==True)).\
group_by(Tag.id).\
order_by(db.func.count(PostVersion.id).desc()).\
all()
Upvotes: 1