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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:20:56