【发布时间】:2018-08-26 01:32:33
【问题描述】:
我正在使用 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 }
})
}
那是我得到致命错误的时候。研究表明,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 模型实例,而其他实体返回健康的,那就不好了。
如果没有include,我们应该如何在graphql-sequelize 的resolver 中实现预加载?
软件包版本:
apollo-server-express@1.3.2
graphql-sequelize@5.6.1
sequelize@4.35.1
dataloader-sequelize@1.6.3
【问题讨论】:
标签: sequelize.js graphql apollo-server