Django prefetch_related 查询未按要求工作,需要进行故障排除
Django prefetch_related query not working as required, troubleshooting needed
我有两个简单的 Django 模型:
class PhotoStream(models.Model):
cover = models.ForeignKey('links.Photo')
creation_time = models.DateTimeField(auto_now_add=True)
class Photo(models.Model):
owner = models.ForeignKey(User)
which_stream = models.ManyToManyField(PhotoStream)
image_file = models.ImageField(upload_to=upload_photo_to_location, storage=OverwriteStorage())
目前我仅有的数据是6张照片,全部属于1个照片流。在形成照片流查询集时,我正在尝试以下操作来预取所有相关照片:
queryset = PhotoStream.objects.order_by('-creation_time').prefetch_related('photo_set')
for obj in queryset:
print obj.photo_set.all()
#print connection.queries
通过调试工具栏检查,我发现上面执行的查询次数与删除语句的 prefetch_related
部分时执行的查询次数完全相同。这显然是行不通的。我也试过 prefetch_related('cover')
- 那也没用。
谁能指出我做错了什么,以及如何解决?我的目标是获取查询集中每个照片流的所有相关照片。我怎么可能这样做?
在 运行 之后打印 connection.queries
for 循环包括:
SELECT ("links_photo_which_stream"."photostream_id") AS "_prefetch_related_val", "links_photo"."id", "links_photo"."owner_id", "links_photo"."image_file" FROM "links_photo" INNER JOIN "links_photo_which_stream" ON ("links_photo"."id" = "links_photo_which_stream"."photo_id") WHERE "links_photo_which_stream"."photostream_id" IN (1)
注意:我已经简化了我在问题中发布的模型,因此上面的查询不包括实际出现在输出中但与此问题无关的一些字段。
以下是 prefetch_related
的部分摘录:
**prefetch_related**
, on the other hand, does a separate lookup for each relationship, and does the ‘joining’
in Python.
还有一些:
>>> Pizza.objects.all().prefetch_related('toppings')
This implies a self.toppings.all()
for each Pizza; now each time self.toppings.all()
is called, instead of having to go to the database for the items, it will find them in a prefetched QuerySet cache that was populated in a single query.
因此,您看到的 查询数量 将始终相同,但如果您使用 prefetch_related
,则无需为每个 photostream
访问数据库它将点击它已经构建的 prefetched QuerySet cache
并从那里获取 photo_set
。
我有两个简单的 Django 模型:
class PhotoStream(models.Model):
cover = models.ForeignKey('links.Photo')
creation_time = models.DateTimeField(auto_now_add=True)
class Photo(models.Model):
owner = models.ForeignKey(User)
which_stream = models.ManyToManyField(PhotoStream)
image_file = models.ImageField(upload_to=upload_photo_to_location, storage=OverwriteStorage())
目前我仅有的数据是6张照片,全部属于1个照片流。在形成照片流查询集时,我正在尝试以下操作来预取所有相关照片:
queryset = PhotoStream.objects.order_by('-creation_time').prefetch_related('photo_set')
for obj in queryset:
print obj.photo_set.all()
#print connection.queries
通过调试工具栏检查,我发现上面执行的查询次数与删除语句的 prefetch_related
部分时执行的查询次数完全相同。这显然是行不通的。我也试过 prefetch_related('cover')
- 那也没用。
谁能指出我做错了什么,以及如何解决?我的目标是获取查询集中每个照片流的所有相关照片。我怎么可能这样做?
在 运行 之后打印 connection.queries
for 循环包括:
SELECT ("links_photo_which_stream"."photostream_id") AS "_prefetch_related_val", "links_photo"."id", "links_photo"."owner_id", "links_photo"."image_file" FROM "links_photo" INNER JOIN "links_photo_which_stream" ON ("links_photo"."id" = "links_photo_which_stream"."photo_id") WHERE "links_photo_which_stream"."photostream_id" IN (1)
注意:我已经简化了我在问题中发布的模型,因此上面的查询不包括实际出现在输出中但与此问题无关的一些字段。
以下是 prefetch_related
的部分摘录:
**prefetch_related**
, on the other hand, does a separate lookup for each relationship, and does the‘joining’
in Python.
还有一些:
>>> Pizza.objects.all().prefetch_related('toppings')
This implies a
self.toppings.all()
for each Pizza; now each timeself.toppings.all()
is called, instead of having to go to the database for the items, it will find them in a prefetched QuerySet cache that was populated in a single query.
因此,您看到的 查询数量 将始终相同,但如果您使用 prefetch_related
,则无需为每个 photostream
访问数据库它将点击它已经构建的 prefetched QuerySet cache
并从那里获取 photo_set
。