Python prefetch_related不缓存数据

时间:2018-08-08 17:01:08

标签: python sql django caching

这是我的问题:

我在外部数据库上有两个表,它们看起来像这样:

class cell(models.Model):
    reference = models.CharField(max_length=36)   

class specs(models.Model):
    value_str = models.CharField(max_length=255, blank=True, null=True)
    name = models.CharField(max_length=255)
    linked = models.ForeignKey(cell, models.DO_NOTHING)

所以牢房有多个规格指向他。
我正在运行查询以获取一些具有其规格的单元格:

cells = cell.objects.using('db_name').prefetch_related('specs_set').all()

此查询后,我需要在每个单元格中使用一些specs对象的“ for”:

for cell in cells :
    print(cell.reference)
    spec = cell.specs_set.filter(name='spec_name').first()
    print(spec.value_str)

这有效,但是据我对prefetch_related的理解,应该通过第一个查询来缓存specs对象,因此,我不必在每次迭代时都运行另一个查询来获取我的“ spec_name”。

可以肯定的是,我在笔记本电脑上运行了Wireshark,然后…感到惊讶……在每次迭代中都进行了查询:(
因此,我有第一个返回所有单元格的查询-对于每个单元格,我都有一个新查询,该查询获取了所需的规格。第一个还可以,但是以下所有问题对我来说都是个问题,不应该在那里。

我的问题:
我做错了什么?

预先感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

与预取相关的用法仅在需要所有实例时使用,但是在需要过滤时不起作用。例如:

for cell in cells :
    print(cell.reference)
    spec = cell.specs_set.all()
    print(spec.value_str)

这将起作用

但是如果您需要:

for cell in cells :
    print(cell.reference)
    spec = cell.specs_set.filter(name='spec_name').first()
    print(spec.value_str)

这行不通。

请参阅文档https://docs.djangoproject.com/en/2.1/ref/models/querysets/#prefetch-related

要进行过滤,您应该像这样使用Prefetch:

from django.db.models import Prefetch

qs = cpecs.objects.filter(name='spec_name')

cells = cell.objects.using(
    'db_name'
).prefetch_related(
    Prefetch('specs_set', queryset=qs)
).all()

请参阅文档https://docs.djangoproject.com/en/2.1/ref/models/querysets/#prefetch-objects

我不了解“第一”,我认为这首先不会起作用,但是您可以使用:

list(cell.specs_set.filter(name='spec_name'))[0]

代替先尝试其他方法

相关问题