为 Peewee 中的对象集获取最新的相关对象

Fetching most recent related object for set of objects in Peewee

假设我有一个对象模型 A,它使用 sqlite 后端在 Peewee 中与 B 建立一对多关系。我想获取一些 A 集并将每个集与他们最近的 B 连接起来。他们有没有循环执行此操作的方法?

class A(Model):
    some_field = CharField()
class B(Model):
    a = ForeignKeyField(A)
    date = DateTimeField(default=datetime.datetime.now)

天真的方法是调用 order_by 和 limit(1),但这会应用于整个查询,所以

q = A.select().join(B).order_by(B.date.desc()).limit(1)

自然会产生单例结果,

q = B.select().order_by(B.date.desc()).limit(1).join(A)

我要么使用了错误的预取,要么它对此不起作用,因为

q1 = A.select()
q2 = B.select().order_by(B.date.desc()).limit(1)
q3 = prefetch(q1,q2)
len(q3[0].a_set)
len(q3[0].a_set_prefetch)

根据需要,这些集合的长度都不为 1。有人知道怎么做吗?

我意识到我需要了解函数和 group_by。

q = B.select().join(A).group_by(A).having(fn.Max(B.date)==B.date)

仅当您需要最新日期而不是日期的最后一个条目时,才可以这样使用它。如果最后一个日期条目不是默认日期 (datetime.datetime.now),则此查询将是错误的。

您可以找到最后一个日期条目:

last_entry_date = B.select(B.date).order_by(B.id.desc()).limit(1).scalar()

以及具有此日期的相关 A 记录:

A 和 B 字段:

q = A.select(A, B).join(B).where(B.date == last_entry_date)

只有 A 字段:

q = B.select().join(A).where(B.date == last_entry_date)

如果您想找到最新的 B.date(就像您对 fn.Max(B.date) 所做的那样)并将其用作 where 过滤器:

latest_date = B.select(B.date).order_by(B.date.desc()).limit(1).scalar()