SQLAlchemy中关系的高效查询

时间:2014-01-07 19:28:20

标签: python sql database optimization sqlalchemy

一点背景:我正在创建一个Web应用程序(使用Flask)在组织内部使用。 webapp将有一个非常简单的留言板,允许用户发布和评论帖子。

我这样做有几个原因 - 主要是为了获得Flask的经验并更好地理解sqlalchemy。

这是删除了一些非重要信息的数据库架构:

class User(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    # information about user
    posts = db.relationship('Post', backref = 'author', lazy = 'dynamic')
    comments = db.relationship('Comment', backref = 'author', lazy = 'dynamic')

class Post(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    # information about posts (title, body, timestamp, etc.)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    comments = db.relationship('Comment', backref = 'thread', lazy = 'dynamic')

class Comment(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    # information about comment (body, timestamp, etc)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))   # author
    post_id = db.Column(db.Integer, db.ForeignKey('post.id'))   # thread

当我渲染消息视图时,我希望能够显示每个消息的以下信息的线程表:

  • 标题
  • 作者
  • #回复
  • 上次修改时间

现在,我获取消息的查询如下所示:

messages = Post.query.filter_by(post_type = TYPE_MESSAGE).order_by('timestamp desc')

通过该查询,我可以轻松获得每个帖子的标题和作者。但是,它目前按消息创建日期排序(我知道这是错误的,我知道为什么),我不能轻易得到回复的数量。

如果我循环浏览消息以在应用程序中呈现它们,我可以访问message.comments属性并使用它来查找长度并获取最新评论的时间戳,但我是否正确假设要获取该数据需要另一个数据库查询(访问message.comments)?

既然如此,我可以通过一个查询得到所有消息的列表(好)但是如果我有n个消息,则需要n个额外的数据库查询来填充消息查看我想要的信息,这远远没有效率。

这让我想到了我的主要问题:是否可以像在常规SQL查询中一样使用SQLAlchemy的聚合运算符来在{{1}的原始查询中获取COUNT(comments)MAX(timestamp) }?或者,还有其他解决方案,我还没有探索过吗?理想情况下,我希望能够在一个查询中完成所有操作。我查看了SQLAlchemy文档,找不到这样的内容。谢谢!

1 个答案:

答案 0 :(得分:0)

为了计算,你可以尝试这个(例子):

session.query(Comment).join(Post).filter_by(id=5).count()

sess.query(Comment).join(Post).filter(Post.id==5).count()

并且,是的,您可以使用聚合:

sess.query(func.max(Comment.id)).join(Post).filter_by(id=5).all()

sess.query(func.max(Comment.id)).join(Post).filter(Post.id==5).all()