小背景:我正在创建一个Web应用程序(使用Flask)以便在组织内部使用。该webapp将有一个非常简单的留言板,允许用户张贴和评论帖子。高效查询SQLAlchemy中的关系
我这样做是出于几个原因 - 主要是为了获得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
额外的数据库查询来填充消息视图,其中I想要,这远没有效率。
这使我想起我的主要问题:是否有可能使用聚合运营SQLAlchemy的,你会在一个普通的SQL查询来获取COUNT(comments)
和MAX(timestamp)
在messages
原始查询?或者,还有没有探索过的另一个解决方案呢?理想情况下,我希望能够在一个查询中完成这一切。我查看了SQLAlchemy文档,找不到像这样的东西。谢谢!
我相信大多数论坛软件通过在'Post'级别存储这两个值来解决这个问题。它消除了频繁显示信息的联接需求,特别是当您检索多个帖子时。 – dirn
这很有道理。从你所说的话来看,似乎我不得不将一个属性添加到名为“Post”的回复中,并在每次添加评论时增加它。那么'Post'必须具有像add_comment(c)'函数的东西(不一定是好的设计 - 当注释被删除时会发生什么?),还是有另一种方法可以通过SQLAlchemy来添加注释引用特定“Post”的数据库? – jcomo
就我个人而言,我会用数据库中的触发器来做到这一点。如果你想把东西放在ORM中,[Flask-SQLAlchemy支持一些信号](http://pythonhosted.org/Flask-SQLAlchemy/signals.html)。 – dirn