Извлечение самого последнего связанного объекта для набора объектов в Peewee
Предположим, у меня есть объектная модель A с отношением один-ко-многим с B в Peewee, использующим бэкэнд sqlite. Я хочу получить некоторый набор 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, как хотелось бы. Кто-нибудь знает как это сделать?
2 ответа
Я понимаю, что мне нужно понять функции и 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()