Sequelize非空约束报错:用户头像上传时字段不能为空问题
问题描述
我希望用户注册时,user模型的firstName和lastName字段允许为空,待用户登录后再上传个人头像。但测试代码时触发错误:
{"message": "notNull Violation: users.firstName cannot be null,\nnotNull Violation: users.lastName can not be null}
头像上传相关代码(Multer配置+接口)
const Storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, './public/images') }, filename: (req, file, callBack) => { callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname)) }, }); const multerFilter = (req, file, cb) => { var ext = path.extname(file.originalname); if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') { cb(new Error('Only images are allowed')) } cb(null, true) }; const updateFile = multer({ storage: Storage, limits: 3 * 1024 * 1024, //max 3MB file upload fileFilter: multerFilter, }); router.post("/profile" , updateFile.single("upload"), async(req, res)=>{ console.log('hello') console.log(req.file) if (req.file == undefined) { return res.status(400).json({ message:'please select the file' }); } console.log('inside the db') try { await users.create({ image: req.file.filename }) .then(msg=>{ res.status(200).json({ message: "profile is uploaded successfully!" }); }); console.log('outside the db') } catch (error) { res.status(500).json({ message: error.message }); } });
Sequelize用户模型代码
import { Sequelize } from "sequelize"; import db from "../config/Database.js"; const Datatypes = Sequelize; const users = db.define('users', { uuid:{ type: DataTypes.STRING, defaultValue: DataTypes.UUIDV4, allowNull: false, validate: { notEmpty: true } }, firstName: { type: DataTypes.STRING, allowNull: false, }, lastName:{ type: DataTypes.STRING, allowNull: false, }, email: { type: DataTypes.STRING, allowNull: false, unique: true, validate: { notEmpty: true, isEmail: true, }, }, password: { type: DataTypes.STRING, allowNull: false, validate: { notEmpty: true } }, image: { type: DataTypes.STRING, allowNull: true }, role:{ type: DataTypes.STRING, allowNull: false, validate:{ notEmpty: true } } }, { freezeTableName: true }) export default users;
解决方案
1. 修改模型字段规则,允许firstName和lastName为空
在Sequelize用户模型中,将firstName和lastName的allowNull属性改为true,这样数据库层面就允许这两个字段为空:
firstName: { type: DataTypes.STRING, allowNull: true, // 原false改为true }, lastName:{ type: DataTypes.STRING, allowNull: true, // 原false改为true },
修改后需要同步模型到数据库,建议使用db.sync({ alter: true })(会安全调整表结构,不丢失现有数据),或者通过迁移脚本更新。
2. 修复头像上传接口的逻辑错误
当前接口使用users.create()创建新用户,但只传入了image字段,缺少firstName、lastName等必填字段(即使你修改了模型允许为空,创建新用户也不符合头像上传的业务逻辑)。正确逻辑应该是更新当前登录用户的头像,而非创建新用户:
router.post("/profile" , updateFile.single("upload"), async(req, res)=>{ console.log('hello') console.log(req.file) if (req.file == undefined) { return res.status(400).json({ message:'请选择文件' }); } console.log('inside the db') try { // 假设你从请求上下文(如解析后的token)获取到当前登录用户的id,示例为req.user.id const [updatedCount] = await users.update( { image: req.file.filename }, { where: { id: req.user.id } } // 根据实际用户标识字段调整,比如uuid ); if (updatedCount === 0) { return res.status(404).json({ message: "用户不存在" }); } res.status(200).json({ message: "头像上传成功!" }); console.log('outside the db') } catch (error) { res.status(500).json({ message: error.message }); } });
另外,原Multer配置的filename函数存在参数名不一致问题,需修正:
filename: (req, file, callback) => { callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname)) },
内容的提问来源于stack exchange,提问作者rishabh singh
相关产品推荐
相关产品推荐

