仅从 sequelize 原始查询而不是模型实例中获取 dataValues

Posted

技术标签:

【中文标题】仅从 sequelize 原始查询而不是模型实例中获取 dataValues【英文标题】:Get only dataValues from sequelize raw query instead of Model instance 【发布时间】:2019-05-17 10:27:57 【问题描述】:

我正在使用 sequelize 并使用原始查询从表中获取数据。但是我得到了所有模型实例,而我只需要 dataValues。 我的设置如下所示:

const sequelize = new Sequelize(
  database: process.env.PGDATABASE,
  username: process.env.PGUSER,
  password: process.env.PGPASS,
  host: process.env.PGHOST,
  port: process.env.PGPORT,
  dialect: "postgres"
);

getPostGres: () => 
    return sequelize;
  

我查询数据库的方式是这样的:

let messageRatingsArr = await getPostGres().query(
    `SELECT mr.support_email, mr.support_name,
    (select count(mrn."chatId") as total FROM message_ratings as mrn WHERE mrn."ratingType"='NEGATIVE' and mr.support_email = mrn.support_email) as negative,
 (select count(mrp."chatId") as total FROM message_ratings as mrp WHERE mrp."ratingType"='POSITIVE' and mr.support_email = mrp.support_email) as positive,
 (select count(mrm."chatId") as total FROM message_ratings as mrm WHERE mrm."ratingType"='MIXED' and mr.support_email = mrm.support_email) as mixed,
 (select count(mru."chatId") as total FROM message_ratings as mru WHERE mru."ratingType"='NEUTRAL' and mr.support_email = mru.support_email) as neutral
      FROM message_ratings mr 
      WHERE mr."createdAt" >= '$properFromDate' AND mr."createdAt" <= '$properToDate'
     group by mr.support_email, mr.support_name 
     limit $args.count offset $args.offset `,
    
      model: MessageRatingPG,
      mapToModel: true
    
  );
  let messageRatings = messageRatingsArr.map(item=>
    return item.dataValues;
  )
  let result = connectionFromArray(messageRatings, args);
  result.totalCount = messageRatings.length;
  return result;

如您所见,由于我正在映射查询中的数据,其中包含各种数据,如 dataValues、_options、isNewRecord 等,如果我有一个大数据集,则循环遍历数组效率不高,所以我该怎么做才能只获取 dataValues?

【问题讨论】:

【参考方案1】:

来自https://sequelize.org/master/manual/raw-queries.html

如果您不需要访问元数据,您可以传入查询类型来告诉 sequelize 如何格式化结果。例如,对于一个简单的选择查询,您可以这样做:

sequelize.query("SELECT * FROM `users`",  type: sequelize.QueryTypes.SELECT)
  .then(users => 
    // We don't need spread here, since only the results will be returned for select queries
  )

现在,查看您的代码,并与文档中的下一段进行比较:

第二个选项是模型。如果您传递模型,则返回的数据将是该模型的实例。

// Callee is the model definition. This allows you to easily map a query to a predefined model
sequelize
  .query('SELECT * FROM projects', 
    model: Projects,
    mapToModel: true // pass true here if you have any mapped fields
  )
  .then(projects => 
    // Each record will now be an instance of Project
  )

我建议从您的原始代码中删除以下内容:


  model: MessageRatingPG,
  mapToModel: true

并将其替换为 type: sequelize.QueryTypes.SELECT

【讨论】:

【参考方案2】:

您必须在查询中添加属性raw。来自docs

有时您可能会期待一个您想要的海量数据集 显示,无需操纵。对于您选择的每一行,Sequelize 创建具有更新、删除、获取功能的实例 关联等。如果您有数千行,这可能需要一些 时间。如果您只需要原始数据并且不想更新任何内容, 你可以这样做来获取原始数据。

 Project.findAll( where:  ... , raw: true )

【讨论】:

OP 显然使用.query() 来写出他的原始查询。这与您建议的Model.findAll() 不兼容。

以上是关于仅从 sequelize 原始查询而不是模型实例中获取 dataValues的主要内容,如果未能解决你的问题,请参考以下文章

使用 Sequelize 仅从行和关联中获取值

SQLAlchemy 仅从连接表中选择列

在使用 Sequelize 作为 ORM 的 Sails 应用程序中使用原始查询

hasMany调用的东西不是Sequelize.Model的实例

获取由 sequelize.js 生成的原始查询 [重复]

如何从sequelize中的实例中排除关联属于多?