我正在尝试使用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'
我需要在迁移中使用哪种正确的语法?
谢谢, - 戴夫
答案 0 :(得分:0)
如错误消息所示,您无法自动将interval
转换为bigint
。您不能简单地投射它,因此建议的using time_in_ms::bigint
也不会有效。
建议部分正确,但更改列类型时手动排序类型转换的常用方法是在ALTER TABLE中使用USING子句,这样您只需确定要用于转换的表达式interval
为bigint
的毫秒数。
在数据库中切片和切块时间类型的常用方法是使用extract
:
<强> 9.9.1。 EXTRACT,date_part
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'