【问题标题】:How do I change my Rails datatype to PostGres bigint?如何将我的 Rails 数据类型更改为 PostGres bigint?
【发布时间】:2016-06-13 20:05:03
【问题描述】:

我正在尝试使用 Rails 4.2.4 和 PostGresql 运行以下 Rails 迁移……

class ChangeTimeInMsColInMyObjectTimes < ActiveRecord::Migration
  def change
    change_column :my_object_times, :time_in_ms, :integer, :limit => 8
  end
end

但它会导致以下错误。我

rake db:migrate
== 20160613195631 ChangeTimeInMsColInMyObjectTimes: migrating =====================
-- change_column(:my_object_times, :time_in_ms, :integer, {:limit=>8})
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::DatatypeMismatch: ERROR:  column "time_in_ms" cannot be cast automatically to type bigint
HINT:  You might need to specify "USING time_in_ms::bigint".
: ALTER TABLE "my_object_times" ALTER COLUMN "time_in_ms" TYPE bigint
/Users/davea/.rvm/gems/ruby-2.3.0@global/gems/activerecord-4.2.5.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:155:in `async_exec'
/Users/davea/.rvm/gems/ruby-2.3.0@global/gems/activerecord-4.2.5.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:155:in `block in execute'
/Users/davea/.rvm/gems/ruby-2.3.0@global/gems/activerecord-4.2.5.1/lib/active_record/connection_adapters/abstract_adapter.rb:472:in `block in log'
/Users/davea/.rvm/gems/ruby-2.3.0@global/gems/activesupport-4.2.5.1/lib/active_support/notifications/instrumenter.rb:20:in `instrument'

我需要在迁移中使用什么正确的语法?

谢谢,- 戴夫

【问题讨论】:

  • time_in_ms 现在是什么类型?
  • 它的类型是“interval”。

标签: postgresql ruby-on-rails-4 migration rails-activerecord bigint


【解决方案1】:

正如错误消息所述,您无法自动将 interval 转换为 bigint。您也不能简单地投射它,因此建议的 using time_in_ms::bigint 也不起作用。

这个建议有一部分是正确的,在更改列的类型时手动排序类型转换的常用方法是在 ALTER TABLE 中使用 USING 子句,因此您需要做的就是确定使用哪个表达式来转换interval 到毫秒数为bigint

在数据库中对时间类型进行切片和切块的常用方法是使用extract

9.9.1。提取,日期部分

EXTRACT(field FROM source)

extract 函数从日期/时间值检索子字段,例如年或小时。 [...] extract 函数返回 double precision 类型的值。

在这种情况下,字段是您感兴趣的时间部分,epoch 可能是您所追求的:

epoch
[...] 对于间隔值,间隔中的总秒数

extract 以双精度形式为您提供秒数,因此您必须自己将秒数转换为毫秒数。比如:

using extract(epoch from time_in_ms) * 1000

应该可以解决问题。在迁移中,这将是:

change_column :my_object_times, :time_in_ms, :integer, :limit => 8, :using => 'extract(epoch from time_in_ms) * 1000'

change_column :my_object_times, :time_in_ms, :bigint, :using => 'extract(epoch from time_in_ms) * 1000'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-03
    • 2021-03-04
    • 2018-05-25
    • 2016-01-28
    • 2023-03-20
    • 2017-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多