【问题标题】:Sequelize set timezone to querySequelize 设置时区查询
【发布时间】:2018-02-22 16:30:47
【问题描述】:

我目前在我的项目中使用 Sequelizepostgres。我需要更改查询,因此它返回带有时区偏移量的 created_at 列。

var sequelize = new Sequelize(connStr, {
dialectOptions: {
    useUTC: false //for reading from database
},
timezone: '+08:00' //for writing to database

});

但这会影响整个数据库。但我只需要使用时区进行选择查询。有人知道怎么做吗?

【问题讨论】:

  • 您可能需要为此使用带有timestamp AT TIME ZONE 的原始查询
  • 我也试过了,它有效,但不正确。当我在查询生成器中运行查询时,它可以工作。但我续集它计算错误。
  • 这有什么更新吗?我面临着类似的问题

标签: postgresql select sequelize.js timezone-offset


【解决方案1】:

这是我的配置方式:

  dialectOptions: {
    dateStrings: true,
    typeCast: true,
  },
  timezone: 'America/Los_Angeles',

http://docs.sequelizejs.com/class/lib/sequelize.js~Sequelize.html

【讨论】:

  • 无论我将时区设置为什么,在 phpmyadmin 中我仍然会在我的服务器上获得 created_at 和 updated_at 时间。单击该字段也会显示不正确的时区。我可能做错了什么?
  • 也许这只是一个表象
  • 这适用于 postgres 吗?我已经尝试过了,但没有奏效。我尝试了几种方法,但时区设置似乎不适用于 sequelize 和 postgres
【解决方案2】:

我建议将moment.js 与以下方法之一结合使用:

如果您需要参数化时区,那么您可能需要为每个单独的查询添加偏移量,或者在表中添加一个指示时区的附加字段,因为 sequelize 似乎不允许参数化的 getter。

例如:

const moment = require('moment.js');
const YourModel = sequelize.define('your_model', {
  created_at: {
    type: Sequelize.DATE,
    allowNull: false,
    get() {
      return moment(this.getDataValue('created_at'))
        .utcOffset(this.getDataValue('offset'));
    },
  },
});

另一种可能性是以类似的方式扩展模型原型的实例方法,这允许您在需要 created_at 值时指定偏移量:

const moment = require('moment.js');
YourModel.prototype.getCreatedAtWithOffset = function (offset) {
  return moment(this.created_at).utcOffset(offset);
};

【讨论】:

    【解决方案3】:

    要正确使用时区查询,请准备您的 pg 驱动程序,请参阅详细信息here:

    const pg = require('pg')
    
    const { types } = pg
    
    // we must store dates in UTC
    pg.defaults.parseInputDatesAsUTC = true
    
    // fix node-pg default transformation for date types
    // https://github.com/brianc/node-pg-types
    // https://github.com/brianc/node-pg-types/blob/master/lib/builtins.js
    types.setTypeParser(types.builtins.DATE, str => str)
    types.setTypeParser(types.builtins.TIMESTAMP, str => str)
    types.setTypeParser(types.builtins.TIMESTAMPTZ, str => str)
    

    必须在启动 Sequelize 实例之前对其进行初始化。

    您现在可以运行一个查询,指明您想要获取日期的时区

    假设我们进行 SQL 查询,选择所有用户的字段,并在时区 'Europe/Kiev' 中“createdAt”:

    SELECT *, "createdAt"::timestamptz AT TIME ZONE 'Europe/Kiev' AS "createdAt" FROM users WHERE id = 1;
    
    # or with variables
    SELECT *, "createdAt"::timestamptz AT TIME ZONE :timezone AS "createdAt" FROM users WHERE id = :id;
    

    对于 Sequelize(对于用户模型),它将是这样的:

    sequelize.findOne({
      where: { id: 1 },
      attributes: {
        include: [
          [sequelize.literal(`"User"."createdAt"::timestamptz AT TIME ZONE 'Europe/Kiev'`), 'createdAt'],
          
          // also you can use variables, of course remember about SQL injection:
          // [sequelize.literal(`"User"."updatedAt"::timestamptz AT TIME ZONE ${timeZoneVariable}`), 'updatedAt'],
        ]
      }
    });
    

    【讨论】:

      猜你喜欢
      • 2019-11-28
      • 2015-07-06
      • 1970-01-01
      • 2014-12-01
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多