如何在SqlAlchemy中设置筛选器,以便在特定的时间段内通过eakeload_all()获取子项

如何在SqlAlchemy中设置筛选器,以便在特定的时间段内通过eakeload_all()获取子项,sqlalchemy,Sqlalchemy,我有一个帖子表,它存储了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))

我有一个帖子表,它存储了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'}
我正在使用eangerload_all()获取属于一个主题的所有回复和评论:

session.query(Topic).options(eagerload_all('replies.comments')).get(topic_id)
我的问题是,如果我只想在某个时间段(例如,本周或本月)收到回复以及这些回复的评论。我应该如何使用过滤器来实现这一点


谢谢

使用
急切加载(u all)
只会立即查询对象
主题
子对象
,而不是第一次请求
回复
和/或
注释
,但是由于您将
主题
对象加载到会话中,其所有相关子对象也会被加载。这为您提供了第一个选项:

选项1:在python代码中进行筛选,而不是在
数据库中进行筛选

基本上在
主题
对象上创建一个方法,类似于

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]
注释的版本稍微复杂一点,因为您需要一个别名来克服SQL语句生成问题,因为所有对象都映射到同一个表名:

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
topic\u id=1
起始日期=日期(2010年9月5日)
截止日期=日期(2010年9月15日)
ralias=别名(回复)
q=会话查询(注释)
q=q.join((ralias,Comment.parent_id==ralias.id))
q=q.filter(ralias.parent\u id==topic\u id)
q=q.filter(Comment.added\u at>=起始日期)

q=q滤波器(Comment.added_at使用
eangerload_all
只会立即查询对象
Topic
子对象,而不是在第一次请求
回复
和/或
注释
时,但是由于您将
Topic
对象加载到会话中,因此其所有相关子对象也将被加载is为您提供了第一个选项:

选项1:在python代码中进行筛选,而不是在
数据库中进行筛选

基本上在
主题
对象上创建一个方法,类似于

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]
注释的版本稍微复杂一点,因为您需要一个别名来克服SQL语句生成问题,因为所有对象都映射到同一个表名:

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
topic\u id=1
起始日期=日期(2010年9月5日)
截止日期=日期(2010年9月15日)
ralias=别名(回复)
q=会话查询(注释)
q=q.join((ralias,Comment.parent_id==ralias.id))
q=q.filter(ralias.parent\u id==topic\u id)
q=q.filter(Comment.added\u at>=起始日期)
q=q.filter(Comment.added\u在