预取关系上的 QuerySet 操作是否命中数据库?
Do QuerySet operations on prefetched relationships hit the database?
假设我在 City
中查询 Workplace
并预取它们所有的 Worker
,这是一个多对多的关系:
workplaces = list(city.workerplace_set.filter(num_employees__lte=350).prefetch_related('Worker'))
如果我对来自任何 Workplace
的 Worker
使用任何 QuerySet
操作,是否会命中数据库?我无法从文档中得出明确的答案。
workplaces_with_interns = [workplace for workplace in workplaces
# is this filter going to query the database?
if workplace.worker_set.filter(salary=0).exists()]
PS:有人可能会指出我可以通过简单地查询 city.workerplace_set
而不是将其设为 list
来得到相同的答案。是的,我知道,但这是不可能的,因为我正在 缓存 workplaces
,这样每次调用执行所有这些操作的函数时都不会访问数据库。
是的。这将命中数据库,因为您是 运行 一个特定的查询 - 存在于过滤器中 - 在原始预取中不存在。
在你的情况下,因为你已经有了工人,所以最好在 Python:
中过滤它们
[workplace for workplace in workplaces
if any(w.salary == 0 for w in workplace.worker_set.all())]
或者,如果这是您需要预取的唯一原因,您可以在原始查询中使用预取对象来仅获取工资为 0 的工人。
(刚刚注意到您使用的是 1.4,它没有 Prefetch 对象。您绝对应该升级;不仅是因为这个原因,而且主要是因为 1.4 非常旧且不受支持,因此肯定存在安全风险。 )
假设我在 City
中查询 Workplace
并预取它们所有的 Worker
,这是一个多对多的关系:
workplaces = list(city.workerplace_set.filter(num_employees__lte=350).prefetch_related('Worker'))
如果我对来自任何 Workplace
的 Worker
使用任何 QuerySet
操作,是否会命中数据库?我无法从文档中得出明确的答案。
workplaces_with_interns = [workplace for workplace in workplaces
# is this filter going to query the database?
if workplace.worker_set.filter(salary=0).exists()]
PS:有人可能会指出我可以通过简单地查询 city.workerplace_set
而不是将其设为 list
来得到相同的答案。是的,我知道,但这是不可能的,因为我正在 缓存 workplaces
,这样每次调用执行所有这些操作的函数时都不会访问数据库。
是的。这将命中数据库,因为您是 运行 一个特定的查询 - 存在于过滤器中 - 在原始预取中不存在。
在你的情况下,因为你已经有了工人,所以最好在 Python:
中过滤它们[workplace for workplace in workplaces
if any(w.salary == 0 for w in workplace.worker_set.all())]
或者,如果这是您需要预取的唯一原因,您可以在原始查询中使用预取对象来仅获取工资为 0 的工人。
(刚刚注意到您使用的是 1.4,它没有 Prefetch 对象。您绝对应该升级;不仅是因为这个原因,而且主要是因为 1.4 非常旧且不受支持,因此肯定存在安全风险。 )