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

Sequelize 6.37.3中model.upsert()报错:不是函数的排查与解决

Sequelize 6.37.3中upsert()报错:TypeError: model.upsert is not a function的解决方案

1. 为什么upsert()不是函数?

upsert()是Sequelize模型类的静态方法,只能通过模型类(比如MyModel.upsert())调用,而非findByPk查询返回的模型实例的方法。你当前代码是拿到数据库中已存在的实例对象后调用upsert,但实例本身并没有这个方法,因此触发类型错误。

2. 如何让请求正常工作?

根据你的业务场景,分两种情况处理:

场景1:仅更新已存在的实例(已通过findByPk查到)

既然已经通过findByPk获取到实例,说明记录在数据库中存在,直接调用实例的save()方法即可完成更新,无需使用upsert:

// my_model.controller.ts 中 MyModelController.put 方法
async put(req, res) {
  const { id } = req.params;
  const updateData = req.body;

  // 获取实例
  const modelInstance = await MyModel.findByPk(id);
  if (!modelInstance) {
    return res.status(404).json({ message: "记录不存在" });
  }

  // 设置属性并验证
  modelInstance.set(updateData);
  await modelInstance.validate();

  // 保存更新
  await modelInstance.save();

  res.json(modelInstance);
}

场景2:实现真正的Upsert(存在则更新,不存在则插入)

如果需求是兼容“更新已有记录”和“插入新记录”两种情况,直接通过模型类调用upsert()方法,无需先查询实例:

// my_model.controller.ts 中 MyModelController.put 方法
async put(req, res) {
  const upsertData = {
    id: req.params.id, // 主键字段,用于判断记录是否存在
    ...req.body
  };

  // 处理关联对象(比如status、address)
  const [instance, created] = await MyModel.upsert(upsertData, {
    // 如果需要同时处理关联模型的upsert,配置include
    include: [
      { model: Status },
      { model: Address }
    ]
  });

  res.json({
    data: instance,
    message: created ? "记录创建成功" : "记录更新成功"
  });
}

关联对象处理注意事项

如果status、address是关联模型,需要确保:

  • 关联模型已经正确定义了与MyModel的关联关系(比如belongsTo、hasOne)
  • 调用upsert时传入的关联数据格式符合Sequelize要求,比如一对一关联可直接传入关联对象的属性或包含主键的对象
  • 如果关联模型也需要执行upsert,需在include选项中配置,且关联模型本身支持静态upsert方法(Sequelize默认支持)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 00:40:04