Sequelize.js 我该如何使用graphql sequelize加载一个没有“include”的关联?

Sequelize.js 我该如何使用graphql sequelize加载一个没有“include”的关联?,sequelize.js,graphql,apollo-server,Sequelize.js,Graphql,Apollo Server,我正在使用graphql sequelize实现graphql端点。我刚刚创建了一个新的辅助实体,并将其与我的一个主实体相关联,现在正在尝试在获取主实体时包含相关的辅助实体。当我尝试实现该提取时,出现以下错误: AssertionError ERR_ASSERTION Include support has been removed in favor of dataloader batching 我以前使用的基于解析器的gql端点如下所示: driver: { type: MyGQLT

我正在使用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'
//     }
// }
那就是我得到致命错误的时候。研究表明graphql sequelize现在不允许包含,而支持sequelize的数据加载器,我目前没有使用,也没有计划使用它

但即使我是,他们希望我们如何在
解析器
中获取相关行的问题仍然没有答案。我发现这表明有一种叫做加入的替代方法,但我还没有找到它的文档,从臀部射击失败了:

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

    })
}
我所能做的就是在例程之后添加一个
,以手动获取关联的模型,然后将该结果附加到主模型的相同位置,如果它是以标准方式获取的(即使用
include
),如下所示:

driver: {
    type: MyGQLTypes.Driver,
    resolve: resolver(Driver, {
        include: { model: Helmet }
    })
}
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
        }

    })
}
{
    dataValues: {
        id: '<uuid>',
        name: 'Tom',
        helmetNumber: '470',
        Helmet: {
            dataValues: {
                number: '470,
                type: 'cool',
                color: 'red'
            }
        }
    }
}
当代码执行并找到我期望的模型时,它无法将找到的模型附加到同一位置

Sqlz实例不是普通散列:它们有一个
dataValues
属性,包含数据库中的原始列值,当您引用
myModel.colName
时,一个隐藏的getter从
myModel.dataValues[colName]
中获取值。实验表明,通过
include
进行的快速加载会导致关联模型出现在
dataValues
结构中,可能还会出现所需的任何隐藏访问器,如:

driver: {
    type: MyGQLTypes.Driver,
    resolve: resolver(Driver, {
        include: { model: Helmet }
    })
}
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
        }

    })
}
{
    dataValues: {
        id: '<uuid>',
        name: 'Tom',
        helmetNumber: '470',
        Helmet: {
            dataValues: {
                number: '470,
                type: 'cool',
                color: 'red'
            }
        }
    }
}
但我认为我们应该避免去摆弄
数据值
,而这似乎是笨手笨脚的

我使用的是apollo server express
,它(正确地)根据GQL模式验证解析器返回值,因此,
驱动程序的GQL类型定义在技术上是此解析函数的下游。我已经开始构建一系列用于组合GQL类型的sugar(特别是当涉及到在原语中嵌入辅助实体时),这种观点鼓励我认为基于
解析器的端点应该具有统一的返回。也就是说,如果某些实体的解析器发出损坏的sqlz模型实例,而其他实体返回正常的实例,这将是不好的

我们应该如何在graphql sequelize的
解析器
中实现无
包含
的即时加载

软件包版本:

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 ]
        })
    })
}
像冠军一样工作。可能有一个我还没有看到的缺点。我想时间会证明一切的


将此选项保留一段时间,以防其他人(包括我自己)有更好的答案。

已经一年没有任何其他贡献了,因此我将自己的答案标记为解决方案。使用dataloader(例如缓存)有什么好处吗?您是否使用graphql sequelize进行任何操作?我相信dataloader本质上是一个可读缓存,我想我已经看到一些人提到它还可以批处理查询。所以,我假设这主要是关于性能的。我选择不使用它,因为通过自动缩放微服务来解决性能问题似乎不那么复杂。