Sequelize:如何预先加载,带有关联,raw:true?

Sequelize: how to eager load, with associations, raw: true?

Node.js 中的预加载是我知道如何使用 Sequelize 的唯一方法。我正在尝试从具有嵌套包含的 MySQL 数据库中导出所有用户调查数据。有超过 50 万行的调查答案,由于为返回的每一行创建一个实例,我的脚本因 运行 内存不足而崩溃。

我想将查询设置为“原始”并只获取简单的对象数据,但它只是 returns 每个包含的第一个关联记录,而不是包含所有这些记录的数组。有没有办法获取所有相关记录并使其成为原始记录?还是 Sequelize 不应该以这种方式用于大型查询?这是我的查询:

db.User.findAll({
  include: [
    { model: db.Referrer }, // has one Referrer
    { model: db.Individual }, // has many Individuals (children)
    {
      model: db.UserSurvey, // has many UserSurveys
      include: {
        model: db.Answer, // UserSurveys have many Answers
        include: {
          model: db.Question // survey question definition
        }
      }
    }
  ],
  raw: true // only returns first Individual, UserSurvey, Answer, etc.
  nest: true // unflattens but does not fix problem
})

如果我限制返回的行数,这个查询就可以正常工作。如果我不限制它,它只会因数据集的大小而崩溃。我已经尝试将原始添加到顶层和各种包含中的任何地方,但似乎没有任何效果。我是否应该尝试将查询基于 Answer,以便所有关系只需要一条记录?或者有没有办法使这些复杂的查询成为原始查询并包括所有相关记录?感谢阅读,这让我难住了几天。

正如 Sequelize 文档所说的 raw 选项:

sequelize will not try to format the results of the query, or build an instance of a model from the result

这意味着如果您有 1 条主记录和 2 条关联记录,您将获得 2 条记录,因为这是 Sequelize 从 SQL-query.

中获取的内容

我想在你的情况下,你应该在一个循环中使用 limitoffset 选项来按块获取记录。这样你就不会导致内存不足的结果。

另外,要获取普通对象而不是模型,请对每个模型使用 get({ plain: true }),如下所示:

const users = db.User.findAll({
  include: [
    { model: db.Referrer }, // has one Referrer
    { model: db.Individual }, // has many Individuals (children)
    {
      model: db.UserSurvey, // has many UserSurveys
      include: {
        model: db.Answer, // UserSurveys have many Answers
        include: {
          model: db.Question // survey question definition
        }
      }
    }
  ]
})
const plainUsers = users.map(x => x.get({ plain: true }))