在将记录从MySql迁移到Postgres时,如何在Rails中设置查询的默认时区或设置datetime值的偏移量

时间:2014-08-29 15:58:03

标签: mysql ruby-on-rails postgresql ruby-on-rails-4

我在models文件夹中创建了一个ruby类,用于连接到遗留MySQL数据库,默认情况下使用 Pacific / PT 作为datetime列。

但是,rails将旧版数据库记录中的datetime值视为 UTC ,而不是 PT / Pacific 。将此值插入Postgres将是不正确的,因为Postgres时间戳(对于rails)是timestamp without time zone(因此,值必须是UTC)。

我怎样才能1)将default_timezone连接设置为太平洋或2)创建某种类型的偏移,以便将值正确转换为UTC?对于后者,偏移如何包含夏令时的细微差别?

以下是我如何确认此问题:

[6] pry(LegacyClient)> @legacy.ClientRecordAddDate.to_yaml
=> "--- 2010-04-11 14:23:01.000000000 Z\n...\n"
[7] pry(LegacyClient)> @legacy.ClientRecordAddDate
=> Sun, 11 Apr 2010 07:23:01 PDT -07:00
[8] pry(LegacyClient)> self.default_timezone
=> :utc

2 个答案:

答案 0 :(得分:0)

首先,找到Postgres数据库群集中实际存在的时区名称:

SELECT *
FROM   pg_timezone_names
WHERE  name ~~* '%Pacif%'
   OR  abbrev = 'PT';

然后在会话中设置此时区:

SET timezone = 'US/Pacific';

这意味着来自timestamp [without time zone]列的值被解释为处于此时区,并且timestamp [with time zone]在输入/输出上相应地从/向UTC偏移。

在Postgres中设置配置参数的方法有很多种。比较:

更多信息:

答案 1 :(得分:0)

我用这个问题辛苦劳作了几天后解决了这个问题。这有点微妙的黑客攻击。 rails中的default_timezone可以是:local:utc。因此,由于rails错误地将我的基于太平洋的Mysql记录误解为“utc”或比UTC低7个小时,我不得不将其更改回UTC(因为它最初被误解为“太平洋”)并将值转换为字符串。然后,ActiveRecord会将字符串转换为Pacific(因为在application.rb中我有config.time_zone = 'Pacific Time (US & Canada)'),然后以正确的UTC格式将其保存到Postgres!

[2] pry(LegacyClient)> @legacy.ClientRecordAddDate.utc.to_s
=> "2010-04-11 14:23:01"

在我的哈希中捕获遗留的mysql值,我会在created_atupdated_at下面有以下内容:

{
...
created_at: @legacy.ClientRecordAddDate.utc.to_s,
updated_at: @legacy.ClientRecordUpdateDate.utc.to_s
}