1

我开发了带有标签支持的简单博客。实际上我想添加标签云功能,我需要计算博客中使用的每个标签。我的博客和标签模型如下所示:

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
4

2 回答 2

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.

于 2013-05-17T13:05:19.430 回答
1

我会这样做(伪代码,不记得正确的炼金术语法,但你应该能够轻松地“转换”它安静)

tags = Tags.findAll()
for tag in tags:
    myDict[tag] = Post.find(tags=tag).count()

在 and 你应该在 myDict 中拥有所有标签及其计数

于 2013-05-17T09:53:43.120 回答