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

如何解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 06:05:35