【问题标题】:ActiveRecord storing time without microsecond precision?ActiveRecord 存储时间没有微秒精度?
【发布时间】:2013-10-03 18:09:35
【问题描述】:

我已经创建了带有 created_at 和 updated_at 列的表,以便 activerecord 自动填充这些字段。我正在使用带有 mysql2 0.3.13 gem 的 rails 4 和 mariadb 5.5

`created_at` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
`updated_at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,

但是当我保存一个项目时,精度不是 (6)/微秒。就像

+----------------------------+----------------------------+
| created_at                 | updated_at                 |
+----------------------------+----------------------------+
| 2013-10-03 17:31:54.000000 | 2013-10-03 17:31:54.000000 |
| 2013-10-03 17:32:32.000000 | 2013-10-03 17:32:32.000000 |
| 2013-10-03 17:33:29.000000 | 2013-10-03 17:33:29.000000 |
| 2013-10-03 17:35:06.000000 | 2013-10-03 17:35:06.000000 |
| 2013-10-03 18:06:20.000000 | 2013-10-03 18:06:20.000000 |
+----------------------------+----------------------------+

如何强制 activerecord 使用微秒精度?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord ruby-on-rails-4


    【解决方案1】:

    根据这个 SO 帖子:

    How to insert a microsecond-precision datetime into mysql?

    5.6.4 之前的 MySQL 不支持任何时间类型的微秒精度。因此,您似乎需要使用 2 列,例如将普通的 created_at 称为 datetime 以及额外的 created_at_usec,即 int

    类似的东西。请注意,您需要一个将两个字段组合为一个的访问器方法,以便于阅读:

    module MicrosecondTimestamps
      extend ActiveSupport::Concern
      module ClassMethods
       # none right now
      end
    
      included do
        before_create :set_created_at
        before_save :set_updated_at
    
        attr_reader :updated_at, :created_at
      end
    
      private
    
      def set_created_at
        if created_at.blank?
          time = Time.now.utc
          self.write_attribute(:created_at, time)
          self.created_at_usec = time.usec
        end
      end
    
      def set_updated_at
        time = Time.now.utc
        self.write_attribute(:updated_at, time)
        self.updated_at_usec = time.usec
      end
    
      def created_at
        @created_at ||= begin
          coerced_time = attributes[:created_at].to_i
          Time.at(coerced_time, created_at_usec)
        end
      end
    
      def updated_at
        @updated_at ||= begin
          coerced_time = attributes[:updated_at].to_i
          Time.at(coerced_time, updated_at_usec)
        end
      end
    
    end
    

    然后你可以将它包含在所有需要它的模型中:

    class Foo < ActiveRecord:Base
      include MicrosecondTimestamps
    end
    

    【讨论】:

    • 因为我所有的模型都需要这种行为,我使用了一个抽象模型来保存这个功能并让我的模型继承。但到目前为止,我仍然得到 .000000。
    • 我正在使用时间戳,所以也许我需要进行更多转换?
    • 我正在使用 mariadb 5.5,它从 5.3 开始就具有微秒精度
    猜你喜欢
    • 1970-01-01
    • 2016-07-14
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    • 2023-02-10
    • 2015-05-29
    • 1970-01-01
    相关资源
    最近更新 更多