gpt4 book ai didi

sequelize.js - 我应该如何在没有 `include` 的情况下使用 graphql-sequelize 急切地加载关联?

转载 作者:行者123 更新时间:2023-12-03 22:18:43 25 4
gpt4 key购买 nike

我正在使用 graphql-sequelize 来实现 GraphQL 端点。我刚刚创建了一个新的辅助实体并将其与我的一个主要实体相关联,现在我正在尝试在获取主要实体时包含相关的辅助实体。当我尝试实现该提取时出现以下错误:

AssertionError ERR_ASSERTION Include support has been removed in favor of dataloader batching

我的旧的基于解析器的 gql 端点如下所示:
driver: {
type: MyGQLTypes.Driver,
resolve: resolver(Driver)
}

我从代码库其他地方的实验中知道这通常有效:
const driver = Driver.getById(`${uuid}`, {
include: { model: Helmet }
})
// yields:
// {
// id: '<uuid>',
// name: 'Tom',
// helmetNumber: '470',
// Helmet: {
// number: '470',
// type: 'cool',
// color: 'red'
// }
// }

所以,在检查了 source code of graphql-sequelize's resolver ,并确定第二个参数传递给 sqlz 访问器,我添加了相同的 include到我的 GQL 解析器,如下所示:
driver: {
type: MyGQLTypes.Driver,
resolve: resolver(Driver, {
include: { model: Helmet }
})
}

那是我得到 fatal error 的时候。研究表明,graphql-sequelize 人们现在不允许 include对于 performance reasons ,支持 sequelize 的数据加载器,我目前没有使用,也没有计划使用。

但即使我是,它也没有回答他们希望我们如何在 resolver 中获取相关行的问题。 .我找到了 a cryptic comment这表明有一个替代方案,称为 join ,但我无法找到它的文档,并且从臀部拍摄失败了:
driver: {
type: MyGQLTypes.Driver,
resolve: resolver(Driver, {

include: { model: Helmet } // fatal error: disallowed

join: { model: Helmet } // no effect, no error

join: Helmet // no effect, no error

})
}

我能想到的就是添加一个 after例程手动获取关联的模型,然后将该结果附加到主模型的相同位置,如果它已被获取标准方式(即使用 include )将出现的位置,如下所示:
driver: {
type: MyGQLTypes.Driver,
resolve: resolver(Driver, {

// can't do this:
include: { model: Helmet }

// so I try to emulate it this way:
after: async (driver) => {

driver.Helmet = await driver.getHelmet()

return driver
}

})
}

当该代码执行并找到我期望的模型时,它无法将找到的模型附加到同一位置。

Sqlz 实例不是普通哈希:它们有 dataValues包含来自数据库的原始列值的属性,并且当您引用 myModel.colName 时,隐藏的 getter 从 myModel.dataValues[ colName ] 获取值.实验表明通过 include 进行预加载导致相关模型出现在 dataValues 中结构,大概连同任何所需的隐藏访问器,如下所示:
{
dataValues: {
id: '<uuid>',
name: 'Tom',
helmetNumber: '470',
Helmet: {
dataValues: {
number: '470,
type: 'cool',
color: 'red'
}
}
}
}

我很确定我可以将获取的模型附加到那里:
driver.dataValues.Helmet = await driver.getHelmet()

但我认为我们应该避免摆弄 dataValues ,这似乎是笨拙的。

我正在使用 apollo-server-express ,它(正确地)根据 GQL 模式验证解析器返回值,因此,我的 Driver 的 GQL 类型定义在技​​术上是此解析功能的下游。我已经开始构建一堆用于组合 GQL 类型的糖(特别是在将次要实体嵌入到主要实体中时),这种观点鼓励我认为 resolver基于 - 的端点应该有统一形状的返回。 IE。如果某些实体的解析器发出损坏的 sqlz 模型实例,而其他实体返回健康的,那就不好了。

我们应该如何在 graphql-sequelize 的 resolver 中实现预加载没有 include ?

软件包版本:
apollo-server-express@1.3.2
graphql-sequelize@5.6.1
sequelize@4.35.1
dataloader-sequelize@1.6.3

最佳答案

我尝试了两件事:

driver: {
type: MyGQLTypes.Driver,
resolve: resolver(Driver, {
after: driver => {
return Driver.findById(driver.id, {
include: [ Helmet ]
})
}
})
}

这行得通,但它两次击中主表,这是巨额。

所以,我决定扔掉graphql-sequelize的“ helper ” resolver ,并直接编程到 apollo-server-express 的 API:
driver: {
type: MyGQLTypes.Driver,
resolve: (parent, args, context, info) => {
return Driver.findById(args.id, {
include: [ Helmet ]
})
})
}

像冠军一样工作。可能有一个我还没有看到的缺点。我想时间会证明一切。

将其打开一段时间,以防其他人(包括我自己)有更好的答案。

关于sequelize.js - 我应该如何在没有 `include` 的情况下使用 graphql-sequelize 急切地加载关联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49329950/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com