如何解决Sequelize中‘Field 'createdAt' doesn't have a default value’错误?
问题分析与解决方案
问题根源
你遇到的问题核心是:Sequelize模型的timestamps逻辑只在通过模型操作数据时生效,但queryInterface.bulkInsert是直接绕过模型、执行原生SQL插入,数据库层面的createdAt字段被设为allowNull: false却没有默认值,所以插入时报错。
之前同类迁移能正常运行,大概率是因为之前的插入操作是通过模型(比如Model.create/bulkCreate)完成的,Sequelize会自动为createdAt填充当前时间;而这次用了直接操作数据库的bulkInsert,就触发了数据库的非空校验。
解决方案
以下是三种可行的解决方式,按需选择:
1. 修改迁移文件,给createdAt添加数据库层面的默认值
这是最彻底的方案,确保不管通过哪种方式插入数据,数据库都会自动填充时间:
// 迁移文件中的createdAt字段配置 createdAt: { allowNull: false, type: Sequelize.DATE, defaultValue: Sequelize.NOW // 适配多数数据库,MySQL也可以用Sequelize.literal('CURRENT_TIMESTAMP') }
修改后重新执行迁移,数据库表的createdAt字段会有默认值,后续bulkInsert无需手动传值。
2. 在seed的bulkInsert中手动传入createdAt值
如果不想修改已执行的迁移,可以直接在seed数据里添加时间字段:
await queryInterface.bulkInsert('testTable', [ { testColumn: 'test1', createdAt: new Date() }, { testColumn: 'test2', createdAt: new Date() } ])
或者用Sequelize提供的函数生成数据库兼容的时间:
await queryInterface.bulkInsert('testTable', [ { testColumn: 'test1', createdAt: Sequelize.fn('NOW') }, { testColumn: 'test2', createdAt: Sequelize.fn('NOW') } ])
3. 改用模型的bulkCreate方法替代queryInterface.bulkInsert
如果希望沿用Sequelize的自动timestamp逻辑,直接用模型的批量创建方法:
// seed文件的up函数 up: async (queryInterface, Sequelize) => { const TestTable = queryInterface.sequelize.model('testTable'); await TestTable.bulkCreate([ { testColumn: 'test1' }, { testColumn: 'test2' } ]); }
bulkCreate会触发模型的钩子,自动为createdAt填充时间,无需手动处理。
内容的提问来源于stack exchange,提问作者Ceintu
相关产品推荐
相关产品推荐

