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してコレクションを反復処理する方法は 1 つだけです。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 に答える