Извлечение самого последнего связанного объекта для набора объектов в 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()
Другие вопросы по тегам