【问题标题】:How to get few last rows from related table?如何从相关表中获取最后几行?
【发布时间】:2021-08-15 00:02:09
【问题描述】:

orm 请求方面需要帮助。

有 2 张桌子。 AuthorBook(例如名称,因此您无需查看逻辑),通过 FK 链接。

class Book(models.Models):
  title = models.Charfield(...)
  
  
class Author(models.Model):
  book = models.ForeignKey(Book)

需要按书籍对作者进行分组并循环浏览它们。问题是如何只选择每本书的最后 50 位作者

我可以这样写:

for book in Book.all()
    for author in  book.author_set.all()[:50]:
        ....

但这不是最佳解决方案。

【问题讨论】:

  • 为什么不是最优的?您正在寻找什么解决方案?
  • 一本作者超过 50 位的书?
  • @WillemVanOnsem 是的。例如我写的tables 的名称。如果需要,可以将Author 更改为BookInstance...
  • @Vincent 我不想在每次 book 迭代中查询数据库...
  • @WillemVanOnsem 我需要这个django orm - stackoverflow.com/questions/2129693/…

标签: sql django django-models django-orm


【解决方案1】:

不好的答案,我没有意识到切片意味着一个新的查询。我的错,不要往下看。

要优化您的查询,您需要使用 prefetch_related() 方法:

prefetch_related() 返回一个查询集 这将在一个批次中自动检索相关对象 对于每个指定的查找。

这与 select_related 的目的相似,因为两者都是 旨在阻止由以下原因引起的大量数据库查询 访问相关对象,但策略大不相同。

select_related 通过创建 SQL 连接并包含字段来工作 SELECT 语句中的相关对象。为此原因, select_related 获取同一数据库查询中的相关对象。 但是,为了避免产生更大的结果集 通过“多”关系加入,select_related 仅限于 单值关系 - 外键和一对一。

另一方面,prefetch_related 对每个 关系,并在 Python 中进行“加入”。这允许它 预取多对多和多对一对象,这是做不到的 使用select_related,除了外键和一对一 select_related 支持的关系。

for book in Book.all().prefetch_related()
    for author in  book.author_set.all()[:50]

您还需要订购 book.author_set 查询集以确保您获得最新条目。

【讨论】:

  • 在这种情况下不会对本书的每一次迭代都有一个查询吗?
  • prefetch_related 在这里没有任何帮助,该切片 [:50] 意味着一个 new 查询,因此实际上所有预取都是浪费的。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多