Sequelize更新accesstoken时触发updatedAt验证错误排查
解决Sequelize更新时
updatedAt cannot be an array or an object错误 从你提供的tokens[0]详细信息里,我一眼看到了关键问题:_options: { raw: true }——这就是触发错误的核心原因!
为什么会出现这个错误?
当你用raw: true查询数据时,Sequelize返回的是纯JavaScript数据对象,而非标准的Sequelize模型实例。虽然这个对象表面上有save()和update()方法,但本质上它只是普通的数据结构,Sequelize无法识别它为模型实例,自然也没法自动处理updatedAt这类内置时间戳字段。
在执行更新操作时,Sequelize会尝试验证所有字段的合法性,包括updatedAt。但因为这是raw对象,updatedAt的内部处理逻辑出现异常,被判定为“数组或对象”,直接触发了验证错误。
解决方案
1. 移除查询时的raw: true选项
这是最直接的根治办法。确保查询tokens时不要设置raw: true,这样返回的就是标准的Sequelize模型实例,save()和update()方法就能正常触发自动更新updatedAt的逻辑:
// 正确的查询方式(不带raw: true) const tokens = await Token.findAll({ where: { id: 1 } }); // 现在调用save或update都不会有问题了 tokens[0].accesstoken = newTokenObj.accesstoken; await tokens[0].save(); // 或者用update方法更简洁 await tokens[0].update({ accesstoken: newTokenObj.accesstoken });
2. 若必须使用raw模式,改用Model级别的update方法
如果你因为业务需求必须用raw: true查询,那不要用实例的update(),直接调用模型的update()方法,这样Sequelize能正确处理自动时间戳:
await Token.update( { accesstoken: newTokenObj.accesstoken }, { where: { id: tokens[0].id } } );
3. 检查模型定义的updatedAt字段
确认你的Token模型中updatedAt字段的定义是正确的,确保它是DATE类型,且没有多余的错误验证规则:
const Token = sequelize.define('accesstoken', { // 其他字段... accesstoken: { type: DataTypes.STRING, allowNull: false } }, { timestamps: true, // 确保这个选项是开启的 // 不要给updatedAt添加额外的自定义验证规则 });
关于validate: false的临时解决
设置validate: false能跳过所有字段的验证逻辑,自然也绕开了updatedAt的类型检查,但这只是权宜之计,会隐藏潜在的字段合法性问题,不推荐长期使用。
内容的提问来源于stack exchange,提问作者陈志翰
相关产品推荐
相关产品推荐

