我有一个表帖子,它存储了3种类型的帖子,主题,回复和评论。每个人都有其父ID。
# Single table inheritance
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('posts.id'))
discriminator = Column(String(1))
content = Column(UnicodeText)
added_at = Column(DateTime)
__mapper_args__ = {'polymorphic_on': discriminator}
class Topic(Post):
replies = relation("Reply")
__mapper_args__ = {'polymorphic_identity': 't'}
class Reply(Post):
comments = relation("Comment")
__mapper_args__ = {'polymorphic_identity': 'r'}
class Comment(Post):
__mapper_args__ = {'polymorphic_identity': 'c'}
我正在使用eagerload_all()来获取所有回复和评论属于一个主题:
session.query(Topic).options(eagerload_all('replies.comments')).get(topic_id)
我的问题是,如果我想在某个时间段(例如本周或本月)仅获得回复和回复评论。我该如何使用过滤器实现这一目标?
谢谢
答案 0 :(得分:1)
使用eagerload_all
只会在第一次请求children
和/或Topic
时立即查询对象Replies
的{{1}},但是,因为您将Comments
对象加载到会话中,所以它的所有相关子项也将被加载。这为您提供了第一个选择:
选项-1:在python代码中过滤而不是Topic
:
基本上在database
对象上创建一个类似于
Topic
然后,您可以在class Topic(Post):
...
def filter_replies(self, from_date, to_date):
return [r for r in self.replies
if r.added_at >= from_date
and r.added_at <= to_date]
上执行类似的代码来过滤Replies
或其中的任意组合。你明白了。
选项-2:在Comments
级别上过滤:
为了实现此目的,您无需加载database
对象,而是直接在Topic
上过滤。以下查询会返回具有日期过滤器的给定Reply/Comment
的所有Reply
:
Topic
由于您需要别名以便克服SQL语句生成问题,因为所有对象都映射到相同的表名称,因此注释的版本只需要更多一些:
topic_id = 1
from_date = date(2010, 9, 5)
to_date = date(2010, 9, 15)
q = session.query(Reply)
q = q.filter(Reply.parent_id == topic_id)
q = q.filter(Reply.added_at >= from_date)
q = q.filter(Reply.added_at <= to_date)
for r in q.all():
print "Reply: ", r
显然,您可以创建一个将两个和平组合成更全面的查询的功能
要实现topic_id = 1
from_date = date(2010, 9, 5)
to_date = date(2010, 9, 15)
ralias = aliased(Reply)
q = session.query(Comment)
q = q.join((ralias, Comment.parent_id == ralias.id))
q = q.filter(ralias.parent_id == topic_id)
q = q.filter(Comment.added_at >= from_date)
q = q.filter(Comment.added_at <= to_date)
for c in q:
print "Comment: ", c
或this week
类型的查询,您可以将这些过滤器转换为如上所示的日期范围,或使用SA的expression.func功能。