在使用 Sequelize 进行开发时,经常需要使用到时间戳来记录数据的创建和修改时间。而 Sequelize 在定义模型时默认会自动添加 createdAt 和 updatedAt 两个字段,并在每次创建和更新时自动更新这两个字段的值。然而,在一些特殊情况下,这种自动更新机制可能会带来一些问题。
问题表现
假设我们有一个 User 模型,其中定义了一个 fullName 字段用于存储用户的全名。在创建一条记录时,我们只设置了 fullName 字段的值,而没有赋值 createdAt 和 updatedAt 字段。此时,使用下面的代码创建记录:
User.create({ fullName: 'John Doe' });
可以得到以下记录:
{ "id": 1, "fullName": "John Doe", "createdAt": "2021-08-10T08:00:00.000Z", "updatedAt": "2021-08-10T08:00:00.000Z" }
可以看到,Sequelize 在创建记录时自动更新了 createdAt 和 updatedAt 字段的值,并将它们都设置为当前时间。这在大多数情况下是正确的,但在一些情况下可能会带来问题。
例如,我们可能会从外部导入一些数据,这些数据包含了 createdAt 和 updatedAt 字段的值。如果此时直接使用 Sequelize 的 create 方法创建记录,Sequelize 会将原来的 createdAt 和 updatedAt 值覆盖掉,可能导致数据不准确。
解决方法
为了解决上述问题,我们需要在定义模型时显式地告诉 Sequelize 哪些字段需要自动更新,哪些字段不需要自动更新。这可以通过在模型定义中添加 timestamps 和 updatedAt 字段来实现。
具体来说,我们可以在模型定义中添加以下代码:
const User = sequelize.define('User', { // ... 其他字段 ... fullName: DataTypes.STRING }, { timestamps: false, updatedAt: false });
其中,timestamps 设为 false 表示关闭自动添加 createdAt 和 updatedAt 字段的功能。updatedAt 设为 false 表示关闭自动更新 updatedAt 字段的功能。这样一来,我们在创建记录时,Sequelize 就不会自动更新这些字段的值了,而只会使用我们传入的值。
当然,我们还可以根据需要手动更新这些字段的值。例如,在创建记录时显式地指定 createdAt 字段的值:
User.create({ fullName: 'John Doe', createdAt: new Date('2021-01-01T00:00:00Z') });
这样一来,Sequelize 就会将我们传入的 createdAt 值作为记录的创建时间,而不是使用当前时间。
总结
在使用 Sequelize 进行开发时,使用自动添加和自动更新时间戳的功能可以方便地获取记录的创建和修改时间,但在一些特殊情况下可能会带来问题。为了解决这个问题,我们可以在模型定义中设置 timestamps 和 updatedAt 字段来显式地关闭或开启自动更新功能,并在需要的时候手动更新时间戳的值。这样既可以保证记录的准确性,又可以方便地获取时间戳的数值。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64d09d03b5eee0b52578f7a1