【发布时间】:2014-01-25 15:15:38
【问题描述】:
一点背景知识:我正在创建一个在组织内部使用的 Web 应用程序(使用 Flask)。该网络应用程序将有一个非常简单的留言板,允许用户发布和评论帖子。
我这样做有几个原因——主要是为了获得使用 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 中使用聚合运算符来获取 messages 的原始查询中的 COUNT(comments) 和 MAX(timestamp)?或者,还有其他我尚未探索的解决方案吗?理想情况下,我希望能够在一个查询中完成所有这些操作。我查看了 SQLAlchemy 文档,找不到类似的东西。谢谢!
【问题讨论】:
-
我相信大多数论坛软件通过将这两个值存储在
Post级别来解决这个问题。它消除了对频繁显示的信息进行连接的需要,尤其是在您检索多个帖子时。 -
这是有道理的。从您所说的来看,似乎我必须向
Post添加一个名为回复的属性,并在每次添加评论时增加它。Post然后必须有类似add_comment(c)函数的东西(不一定是好的设计——删除评论时会发生什么?)或者是否有另一种方法可以通过 SQLAlchemy 来做到这一点,只要将评论添加到数据库中引用了某个Post? -
我个人会在数据库中使用触发器。如果你想把东西保存在 ORM 中,Flask-SQLAlchemy has support for a couple of signals.
-
感谢您的链接!我不知道为什么我没有考虑触发器。你有使用 SQLAlchemy 的经验吗?为每个评论添加两个触发器(更新回复和最后修改)会使 cmets 的插入速度稍慢一些,但它应该比执行所有这些查询来填充消息视图更快。另外,我使用的是 0.7.9 版。旧版本有类似的支持吗?
-
如果你使用数据库触发器,SQLAlchemy 不需要做任何事情(除非你想执行
CREATE TRIGGER语句)。如果您想使用 SQLAlchemy 中的信号,这些信号已经存在了一段时间。他们肯定在 0.7.9 中。
标签: python sql database optimization sqlalchemy