You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Sequelize findAll()关联查询时抛出TypeError错误求助

问题:Sequelize一对多关联查询嵌套格式异常及报错处理

需求说明

现有invoices表和invoice_items表,为一对多关系(一个invoice对应多个invoice_item),期望通过findAll查询返回如下格式:

[ { name: 'invoice1', invoiceItems: [itemOne, itemTwo] }, ... ]

报错场景及代码

使用以下查询代码时抛出错误:

db.invoice.findAll({
    where: {
        userId: 'ed8fdd40-b807-4e51-b1f5-90fb5b7f6e73'
    },
    include: { all: true, nested: true }
}).then(result => {
    console.log(result)
})

错误堆栈:

c:\Users\brend\Desktop\projects\invoice-server\node_modules\sequelize\lib\model.js:1189
          let associations = result.get(include.association.as);
                                    ^

TypeError: result.get is not a function
    at c:\Users\brend\Desktop\projects\invoice-server\node_modules\sequelize\lib\model.js:1189:37
    at Array.reduce (<anonymous>)
    at c:\Users\brend\Desktop\projects\invoice-server\node_modules\sequelize\lib\model.js:1188:50
    at Array.map (<anonymous>)
    at Model._findSeparate (c:\Users\brend\Desktop\projects\invoice-server\node_modules\sequelize\lib\model.js:1186:39)
    at invoice.findAll (c:\Users\brend\Desktop\projects\invoice-server\node_modules\sequelize\lib\model.js:1153:24)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Node.js v20.10.0

成功但格式不符的查询代码

以下代码查询成功,但返回格式不符合预期(每个关联的invoiceItem对应一个独立的invoice对象):

db.invoice.findAll({
    where: {
        userId: 'ed8fdd40-b807-4e51-b1f5-90fb5b7f6e73'
    },
    include: "invoiceItems",
    raw : true ,
    nest : true
}).then(result => {
    console.log(result)
})

模型配置代码

Invoice模型

module.exports = (sequelize, Sequelize, DataType) => {
    const Invoice = sequelize.define('invoice', {
        id: {
         type: DataType.UUID,
         primaryKey: true
        },
        userId: {
         type: DataType.UUID,
         validate: {
            allowNull: false
         }
        },
        name: {
         type: DataType.STRING(150)
        }
//Additional fields left out here for simplicity
     },{
        underscored: true
     });
     Invoice.associate = models => {
      Invoice.hasMany(models.invoiceItem), {
         foreignKey: "invoiceId"
      }
      Invoice.belongsTo(models.user)
     };

     return Invoice
};

InvoiceItem模型

module.exports = (sequelize, Sequelize, DataType) => {
    const InvoiceItem = sequelize.define('invoiceItem', {
        id: {
         type: DataType.UUID,
         primaryKey: true
        },
        invoiceId: {
         type: DataType.UUID,
         validate: {
            allowNull: false
         }
        },
        userId: {
         type: DataType.UUID,
         validate: {
            allowNull: false
         }
        },
        name: {
         type: DataType.STRING(150)
        }
//Additional fields left out here for simplicity
     },{
        underscored: true
     });
     InvoiceItem.associate = models => {
      InvoiceItem.belongsTo(models.invoice, {
         foreignKey: "invoiceId"
      })
      InvoiceItem.belongsTo(models.user), {
         foreignKey: "userId"
      }};

     return InvoiceItem
};

模型整合index.js

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const sequelize = require('../config/database.js')

const db = {}
db.Sequelize = Sequelize;
db.sequelize = sequelize;

fs.readdirSync(__dirname)
  .filter(file => {
    return (
      file.indexOf('.') !== 0 &&
      file !== basename &&
      file.slice(-3) === '.js' &&
      file.indexOf('.test.js') === -1
    );
  })
  .forEach(file => {
    const model = require(path.join(__dirname, file))(db.sequelize, db.Sequelize, db.Sequelize.DataTypes)
    db[model.name] = model;
  });
Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

module.exports = db;

问题排查及解决思路

核心问题:关联配置语法错误

模型关联配置中存在逗号位置错误,导致关联选项未被正确传入Sequelize,关联关系未正确建立:

  1. Invoice模型中,Invoice.hasMany(models.invoiceItem)后面的逗号写在了括号外,导致{ foreignKey: "invoiceId" }被当作独立语句而非关联选项。
  2. InvoiceItem模型中,InvoiceItem.belongsTo(models.user)同样存在逗号位置错误。

修正后的关联配置

修正Invoice模型的associate方法:

Invoice.associate = models => {
  Invoice.hasMany(models.invoiceItem, {
    foreignKey: "invoiceId"
  });
  Invoice.belongsTo(models.user);
};

修正InvoiceItem模型的associate方法:

InvoiceItem.associate = models => {
  InvoiceItem.belongsTo(models.invoice, {
    foreignKey: "invoiceId"
  });
  InvoiceItem.belongsTo(models.user, {
    foreignKey: "userId"
  });
};

正确的查询代码

去掉raw: true(该配置会返回纯数据库查询结果,无法自动合并关联数据为嵌套数组),通过实例的get({ plain: true })方法转换为纯JS对象,即可得到期望的嵌套格式:

db.invoice.findAll({
  where: {
    userId: 'ed8fdd40-b807-4e51-b1f5-90fb5b7f6e73'
  },
  include: ['invoiceItems']
}).then(result => {
  // 将Sequelize实例转换为嵌套结构的纯JS对象
  const formattedResult = result.map(invoice => invoice.get({ plain: true }));
  console.log(formattedResult);
});

内容的提问来源于stack exchange,提问作者Brenden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 15:15:54