小背景:我正在創建一個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