在使用 Sequelize 进行查询时,我们经常会遇到时间类型字段的数据不一致问题。这是因为 Sequelize 默认将时间类型字段转换为 UTC 时间,而数据库中存储的时间可能是本地时间。本文将介绍如何在 Sequelize 查询时间类型字段时解决数据不一致问题。
问题分析
假设我们有一个 User
模型,其中包含一个 createdAt
字段:
// javascriptcn.com 代码示例 const { Sequelize, DataTypes } = require('sequelize'); const sequelize = new Sequelize('sqlite::memory:'); const User = sequelize.define('User', { name: DataTypes.STRING, createdAt: DataTypes.DATE, }); (async () => { await sequelize.sync({ force: true }); await User.create({ name: 'Alice', createdAt: new Date('2022-01-01T00:00:00+08:00') }); })();
我们在查询时,使用 Sequelize 提供的 findAll
方法:
const users = await User.findAll(); console.log(users[0].createdAt);
输出结果如下:
2021-12-31T16:00:00.000Z
可以看到,输出的时间比我们插入的时间早了 8 小时。这是因为 Sequelize 默认将时间类型字段转换为 UTC 时间,而我们插入的时间是本地时间。
解决方案
方案一:使用 raw
查询
一种解决方案是使用 raw
查询,手动将时间类型字段转换为本地时间。以下是一个示例:
const users = await sequelize.query('SELECT name, datetime(createdAt, "localtime") as createdAt FROM Users', { type: Sequelize.QueryTypes.SELECT, model: User, }); console.log(users[0].createdAt);
输出结果如下:
2022-01-01T00:00:00.000
可以看到,输出的时间与我们插入的时间一致。
方案二:使用 timezone
选项
另一种解决方案是使用 Sequelize 提供的 timezone
选项,将 UTC 时间转换为本地时间。以下是一个示例:
// javascriptcn.com 代码示例 const users = await User.findAll({ attributes: [ 'name', [sequelize.fn('datetime', sequelize.col('createdAt'), 'localtime'), 'createdAt'], ], raw: true, }); console.log(users[0].createdAt);
输出结果如下:
2022-01-01T00:00:00.000
可以看到,输出的时间与我们插入的时间一致。
总结
本文介绍了在 Sequelize 查询时间类型字段时解决数据不一致问题的两种方案。第一种方案是使用 raw
查询,手动将时间类型字段转换为本地时间;第二种方案是使用 Sequelize 提供的 timezone
选项,将 UTC 时间转换为本地时间。这两种方案都可以解决数据不一致的问题,具体选用哪种方案取决于具体情况。
值得注意的是,在实际开发中,我们应该尽可能地避免使用本地时间,而是使用 UTC 时间。这样可以避免在不同地区使用应用程序时出现时间不一致的问题。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6553dca5d2f5e1655dd8f522