SQLAlchemy-“双重查询”的正确方法

时间:2018-09-11 11:29:51

标签: python sqlalchemy

请问这种简单模型的正确方法是什么?

我有两个模型:主题和报告:

class User(UserMixin, Model):
    __tablename__ = 'users'
    id = Column(db.Integer, primary_key=True)
    email = Column(db.String(60), unique=False, nullable=True)
    ...
    reports = db.relationship('Report', backref='user', lazy='dynamic')

class Report(UserMixin, Model):
    __tablename__ = 'reports'
    ...
    created_at = Column(db.DateTime, default=dt.datetime.now)
    user_id = Column(db.Integer, db.ForeignKey('users.id'))

我需要列出上次报告日期的所有用户的列表。

肮脏的方式是:

subjects = User.query.all()
for s in subjects:
    report_date = Report.query.filter(Report.subject_id == s.id).order_by(Report.id.desc()).first()
    print('Subject + Report', s.email, report_date)

请如何以干净的方式创建此列表?

(例如,联接表和查询,带有主题ID +上次访问日期的临时表,将上次访问日期直接存储到表主题...)

谢谢。

1 个答案:

答案 0 :(得分:1)

我不确定您真正需要什么,但是如果要访问列表中彼此的最后一个报告,则只需执行以下操作:

last_report = user.reports.order_by(Report.created_at.desc()).first()

您可能拥有它对用户模型的属性或hybrid_property:

@property
def last_report(self):
    return user.reports.order_by(Report.created_at.desc()).first()

@property
def last_report_date(self):
    return self.last_report.created_at

要获取包含电子邮件和report_date的元组列表,可以执行以下操作:

db.session.query(User.email, func.max(Product.created)).join(Report).group_by(Provider.email).all()

无论如何,如果您有很多条目并且想要向Web用户显示此列表,则应该考虑使用分页。 Flask-sqlalchemy提供了一种简单的方法。