我开发了带标记支持的简单博客。实际上我想添加标签云功能,我需要计算博客中使用的每个标签。 我的Blog和Tag模型如下所示:
class Blog(db.Model, ObservableModel):
__tablename__ = "blogs"
id = db.Column(db.Integer, db.Sequence('blog_id_seq'), primary_key=True)
title = db.Column(db.String(200), unique=True, nullable=True)
tags = relationship('Tag', secondary=tags_to_blogs_association_table)
class Post(db.Model, ObservableModel):
__tablename__ = "posts"
......................
blog = relationship('Blog', backref = db.backref('blogs', lazy='dynamic'))
tags = relationship('Tag', secondary=tags_to_posts_association_table)
class Tag(db.Model):
__tablename__ = "tags"
id = db.Column(db.Integer, db.Sequence('post_id_seq'), primary_key=True)
title = db.Column(db.String(30), unique=False, nullable=True)
我想收集像tag_name : count
这样的对词典,只有一种方法是通过检索包含标签项目的帖子来迭代Blog.tags
集合。
实际上我不确定它是最好的(从性能的角度来看)解决方案,也许flask-sqlalchemy提供了连接功能?
问题:如何使用Flask-SQLAlchemy查询在Python中实现如下:
select
t.id,
t.title,
count(post_id)
from tags t
join tags_to_blogs b on t.id=b.tag_id
join tags_to_posts p on t.id=p.tag_id
group by (t.id)
having b.blog_id=1
答案 0 :(得分:2)
试试这个:
query = db.session.query(Tag, db.count(Post.id))
query = query.filter(
(tags_to_posts_association_table.tag_id == Tag.id) & \
(tags_to_posts_association_table.post_id == Post.id)
)
query = query.group_by(Tag.id)
这会生成此查询:
SELECT tags.id AS tags_id, tags.title AS tags_title, count(posts.id) AS count_1
FROM tags, posts, tags_to_posts
WHERE tags_to_posts.tag_id = tags.id AND tags_to_posts.post_id = posts.id GROUP BY tags.id
更清洁的方式可能是这样的:
query = db.session.query(Tag, db.func.count(Post.id))
# This works but the preferred way is what's below it
#query = query.join(tags_to_posts_association_table, Post)
query = query.join(Post.tags)
query = query.group_by(Tag.id)
这会生成此查询:
SELECT tags.id AS tags_id, tags.title AS tags_title, count(posts.id) AS count_1
FROM tags INNER JOIN tags_to_posts ON tags.id = tags_to_posts.tag_id INNER JOIN posts ON posts.id = tags_to_posts.post_id GROUP BY tags.id
所有这些产生相同的结果,你可以像这样链接它们:
query = db.session.query(Tag.title, db.func.count(Post.id)).join(Post.tags).group_by(Tag.id)
# This will give you a dictionary with keys the tag titles, and values the count of each
# Because you can iterate over the query, which will give you the results
# Or you can use query.all() and use it as you prefer.
results = dict(query)
另外,我不确定它是db.func.count
还是db.count
。无论如何,您始终可以from sqlalchemy import func
并使用func.count
。
答案 1 :(得分:1)
我会这样做(伪代码,不记得正确的炼金术语法,但你应该能够'转换'它很容易安静)
tags = Tags.findAll()
for tag in tags:
myDict[tag] = Post.find(tags=tag).count()
并且你应该在myDict中拥有所有的标签