Sequelize扩展Model类调用findOrCreate创建记录失败报非空约束错误
问题根因
你遇到的报错由两处错误共同导致:
- 模型字段默认值配置错误
Sequelize 定义字段默认值的属性为defaultValue,你当前代码中写的default是无效属性,导致你配置的默认值完全没有生效。配合你设置的allowNull: false规则,创建新记录时GuildPremium、DiscordGuildPrefix等字段没有值,就会触发非空校验报错。 findOrCreate返回值处理错误findOrCreate返回的是Promise对象,你在Promise调用外层直接解构const {NewGuild, created}无法拿到正确返回值;同时findOrCreate的返回结果是数组结构,第一个元素为查询/创建的实例,第二个元素才是标识是否为新创建的布尔值,你用对象解构的方式也不符合返回值规则,且then回调没有接收返回参数,后续逻辑中的created和NewGuild均为undefined,即使校验通过后续更新逻辑也无法正常执行。
修复方案
第一步:修正模型字段配置
将模型中所有字段的default属性替换为defaultValue:
module.exports = class Guilds extends Model { static init(sequelize) { return super.init({ GuildID: { type: DataTypes.INTEGER.UNSIGNED, autoIncrement: true, primaryKey: true, comment: "Guild Database ID" }, DiscordGuildID: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false }, GuildPremium: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false }, DiscordGuildPrefix: { type: DataTypes.TEXT, allowNull: false, defaultValue: process.env.DefaultPrefix }, GuildActive: { type: DataTypes.BOOLEAN, defaultValue: true, comment: "Bot active in Guild?" } }, { tableName: "Guilds", modelName: "Guilds", timestamps: true, sequelize }); };
第二步:修正业务代码
正确处理findOrCreate的Promise返回值,使用数组解构获取结果:
Guilds.findOrCreate({ where: { DiscordGuildID: Guild.id } }) .then(([NewGuild, created]) => { if(created) { console.log(`Guild ${Guild.id} added to Database!`); } else { NewGuild .update({ GuildActive: true }) .then(() => console.log(`Guild ${Guild.id} reactivated in Database!`) ); }; });
相关疑问解答
- Model中定义默认值的作用:只要配置正确,创建记录时没有传入的字段会自动填充默认值,统一维护默认规则,避免业务代码重复编写冗余逻辑。
- 是否需要在业务代码中重复定义默认值:不需要,修正模型配置后即可生效,重复定义反而会导致后续修改默认值时需要多处调整,增加维护成本。
内容的提问来源于stack exchange,提问作者Shadow0013
相关产品推荐
相关产品推荐

