Node Express+Sequelize更新模型报错:updateAttributes不是函数如何解决?
解决Sequelize中
updateAttributes is not a function错误的方案 嘿,这个问题我之前也踩过坑,咱们一步步来解决它~
错误原因分析
你收到的TypeError: updateState.updateAttributes is not a function,核心问题在于:Article.findAll()返回的是一个数组(哪怕只匹配到一条记录),而updateAttributes(现在Sequelize更推荐用update)是Sequelize模型实例的方法,数组对象根本没有这个方法,所以直接调用就会报错。
针对性解决方案
根据你的需求(通过article_id更新单篇文章状态),这里有几种最适合的解决方式:
方案1:用findOne替代findAll(最推荐)
既然你是根据唯一的article_id查询,肯定只会返回单条记录,用findOne直接获取单个模型实例,就能直接调用update方法:
修改helper.js的代码:
publish(req) { // 用findOne替代findAll,返回单个实例而非数组 return Article.findOne({ where: { id: req.query.article_id }, attributes: ['id', 'state'] }) .then(article => { // 先判断文章是否存在,避免后续报错 if (!article) { throw new Error('目标文章不存在'); } // 用update替代updateAttributes(Sequelize新版本已弃用updateAttributes) return article.update({ state: 2 }); }); }
方案2:如果需要处理多条记录(遍历数组更新)
如果你的业务场景可能匹配多条记录,那就遍历findAll返回的数组,逐个调用实例的update方法:
publish(req) { return Article.findAll({ where: { id: req.query.article_id }, attributes: ['id', 'state'] }) .then(articles => { // 用Promise.all并行处理所有实例的更新 return Promise.all(articles.map(article => { return article.update({ state: 2 }); })); }); }
方案3:直接用update批量更新(最高效)
如果不需要先查询原数据,直接用模型的update方法批量更新,一步到位,性能更好:
publish(req) { return Article.update( { state: 2 }, // 要更新的字段 { where: { id: req.query.article_id }, // 更新条件 returning: true // 开启这个选项,会返回更新后的记录数组 } ) .then(([rowsUpdated, updatedArticles]) => { // rowsUpdated是更新的行数,updatedArticles是更新后的实例数组 return updatedArticles; }); }
额外优化:添加错误处理
你的controller.js里没有捕获Promise的异常,会导致未处理的Promise拒绝,建议加上错误处理:
publish(req, res, next) { helper.publish(req) .then((published) => { res.send({ success: true, published }); }) .catch(err => { // 可以直接返回错误响应,或者交给Express的错误处理中间件 res.status(400).send({ success: false, error: err.message }); // next(err); // 也可以用这个交给全局错误处理 }); }
测试验证
修改完成后,调用PUT http://localhost:8080/api/publish?article_id=3555,就能得到你期望的响应:
{ "success": true, "published": { "id": 3555, "state": 2 } }
(如果用方案2或3,published会是数组格式,和你期望的一致)
内容的提问来源于stack exchange,提问作者Tom Bom
相关产品推荐
相关产品推荐

