Sequelize Model.create方法意外触发非空约束错误求助
问题:Sequelize调用User.create时触发非空约束违规错误
我用Sequelize连接MariaDB,连接正常、表已创建,但调用User.create添加用户时,明明传入了非空值,却收到非空约束违规错误。
User类定义
class User extends Model { declare id: number; declare username: string; declare password: string; declare role: string; declare disabled: boolean; declare email?: string; declare phone_number?: string; declare interests?: string; declare first_name?: string; declare last_name?: string; constructor() { super(); } public comparePassword = async (password: string): Promise<boolean> => { return await bc.compare(password, this.password); }; public getPublic = (): User => { const { password, ...publicUser } = this.get(); return publicUser as User; }; }
initUsers初始化函数
export const initUsers = async () => { User.init( { id: { type: DataTypes.INTEGER.UNSIGNED, autoIncrement: true, primaryKey: true, }, username: { type: new DataTypes.STRING(128), allowNull: false, }, password: { type: new DataTypes.STRING(128), allowNull: false, }, role: { type: new DataTypes.STRING(128), allowNull: false, }, disabled: { type: DataTypes.BOOLEAN, allowNull: false, }, email: { type: new DataTypes.STRING(128), allowNull: true, }, phone_number: { type: new DataTypes.STRING(128), allowNull: true, }, interests: { type: new DataTypes.STRING(128), allowNull: true, }, first_name: { type: new DataTypes.STRING(128), allowNull: true, }, last_name: { type: new DataTypes.STRING(128), allowNull: true, }, }, { tableName: "users", sequelize: db.sequelize, modelName: "User", timestamps: true, freezeTableName: true, } ); User.create({ username: "admin", password: await bc.hash("admin", 10), role: "superuser", disabled: false, }); };
错误信息
SequelizeValidationError: notNull Violation: User.username cannot be null, notNull Violation: User.password cannot be null, notNull Violation: User.role cannot be null, notNull Violation: User.disabled cannot be null at InstanceValidator._validate (C:\VVibrant Web Solutions\Onyx Core\node_modules\sequelize\src\instance-validator.js:78:13) at InstanceValidator._validateAndRunHooks (C:\VVibrant Web Solutions\Onyx Core\node_modules\sequelize\src\instance-validator.js:111:7) at InstanceValidator.validate (C:\VVibrant Web Solutions\Onyx Core\node_modules\sequelize\src\instance-validator.js:93:12) at User.save (C:\VVibrant Web Solutions\Onyx Core\node_modules\sequelize\src\model.js:3996:7) at Function.create (C:\VVibrant Web Solutions\Onyx Core\node_modules\sequelize\src\model.js:2280:12) [ERROR] 01:26:21 SequelizeValidationError: notNull Violation: User.username cannot be null, notNull Violation: User.password cannot be null, notNull Violation: User.role cannot be null, notNull Violation: User.disabled cannot be null
DB初始化代码(db.ts)
export const db: { sequelize: Sequelize; } = { sequelize: new Sequelize({ dialect: "mariadb", host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT || "3306"), username: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME, logging: false, sync: { force: true }, }), }; export const initDB = async () => { await db.sequelize.authenticate(); await initUsers(); await initTokens(); await User.sync({ force: true }); await Token.sync({ force: true }); };
问题原因及解决方案
1. 自定义构造函数破坏实例初始化逻辑
User类中手动重写了constructor(),但未正确传递参数给父类构造函数,导致Sequelize无法正确初始化实例属性,验证时判定字段值为null。
解决:删除自定义的constructor
Sequelize的Model类已实现完整构造逻辑,无需手动重写,移除以下代码:
constructor() { super(); }
2. 未等待User.create执行完成
User.create是异步函数,未添加await会导致操作未完成就继续执行后续代码,甚至静默忽略错误。
解决:给User.create添加await
修改initUsers中的创建代码:
await User.create({ username: "admin", password: await bc.hash("admin", 10), role: "superuser", disabled: false, });
3. 重复调用sync干扰模型状态
Sequelize实例配置中已设置sync: { force: true },又在initDB中手动调用User.sync,重复操作可能导致模型状态异常。
解决:移除重复的sync调用
删除initDB中的以下两行:
await User.sync({ force: true }); await Token.sync({ force: true });
内容的提问来源于stack exchange,提问作者Aidan Tilgner
相关产品推荐
相关产品推荐

