【问题标题】:Parse GraphQL query to find fields to be able to prefetch_related?解析 GraphQL 查询以查找能够预取相关的字段?
【发布时间】:2021-11-04 07:14:36
【问题描述】:

当使用来自graphene_django_extras 的DjangoListObjectType 时,我可以在SearchFilter 上定义一个自定义qs 属性。

qs 函数将对象作为其唯一参数,通过它我可以获取请求,进而获取包含查询字段的查询字符串。

在拼凑我自己的解析器来获取这些字段之前,我是不是走错了路?还是有别的东西?

我们的想法是采用一种相当严格的方法,因为我们有 7 种类型的分页列表类型,其中的字段会导致一些不必要的数据库命中,因此我们想要预取一些字段。

Graphene 有一种数据加载器方法,看起来不错,但比仅在 qs 阶段预取它们更复杂。


关于数据加载器的方法,我尝试过类似的方法

class UserLoader(DataLoader):
    def batch_load_fn(self, keys):
        users = {user.id: user for user in User.objects.filter(id__in=keys)}
        return Promise.resolve([users.get(user_id) for user_id in keys])


user_loader = UserLoader()

class BookType(DjangoObjectType):
    ...
    author = graphene.Field(UserType)

    def resolve_author(self, *args, **kwargs):
        return user_loader.load(self.author.id)

哪一种明显感觉完全不对,但是他们在docs中所做的。

【问题讨论】:

标签: django graphene-python graphene-django


【解决方案1】:

使用 DataLoader 是正确的方法,但使用 self.author_id 而不是 self.author.id

通过调用self.author.id,您将获取每本书的作者(每个作者一个 SQL 查询),然后从每个作者那里获取 id 属性。

当您将author ForeignKey 添加到您的Book 模型时,Django 在后台向books 表添加一列—author_id。您可以将此值传递给 DataLoader 并让它使用 SELECT IN 在单个 SQL 查询中获取所有相应的 Authors。

https://docs.djangoproject.com/en/3.2/ref/models/fields/#database-representation

您会注意到 Graphene Docs 在他们的示例中与 best_friend_id 做同样的事情。

【讨论】:

    猜你喜欢
    • 2019-07-28
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2017-10-31
    • 2019-10-03
    • 2020-05-29
    相关资源
    最近更新 更多