我怎样在Rails迁移中将列类型更改为间隔时间类型?

3

我正在使用带有PostGre数据库的Rails 4.2.3。我尝试将我的表中的列类型更改为“interval”类型,因此我尝试了以下迁移:

class ChangeTimeInMsInMyObjectTimes < ActiveRecord::Migration
  def change
    change_column :my_object_times, :time_in_ms, :interval
  end
end

当我运行 "rake db:migrate" 时,我遇到了以下令人失望的错误...
== 20160530164019 ChangeTimeInMsInMyObjectTimes: migrating ========================
-- change_column(:my_object_times, :time_in_ms, :interval)
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 interval
HINT:  You might need to specify "USING time_in_ms::interval".
: ALTER TABLE "my_object_times" ALTER COLUMN "time_in_ms" TYPE interval
/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'
/Users/davea/.rvm/gems/ruby-2.3.0@global/gems/activerecord-4.2.5.1/lib/active_record/connection_adapters/abstract_adapter.rb:466:in `log'

我该如何修改我的迁移以使其工作?


https://gist.github.com/clarkdave/6529610 - Boltz0r
除了将hta tfile放在config/initializers中,我还需要进行其他配置吗?我问这个问题是因为在使用此文件并运行“rake db:migrate”时出现错误,“NameError:undefined method simplified_type' for class ActiveRecord :: ConnectionAdapters :: PostgreSQLColumn'”。 - Dave
1
那个要点试图解决错误的问题,你已经有了interval类型的ActiveRecord支持,你的问题在于错误信息(列“time_in_ms”无法自动转换为类型间隔)以及解决方案(添加适当的USING子句)。 - mu is too short
我不理解。您建议的方法中,我应该如何编写迁移以使其能够在不出错的情况下将列类型更改为“间隔”? - Dave
2个回答

2
问题在于Postgres不知道如何将整数(我假设现在的 time_in_ms 是整数)转换成时间间隔。但是你可以使用 USING 关键字告诉它如何转换旧值。因此,你可以在迁移中使用以下代码:
change_column :my_object_times, :time_in_ms,
              "interval USING (time_in_ms || ' milliseconds')::interval"

请注意,如果您这样做,应编写单独的updown方法,因为使用change_column的方式不会自动可逆。
哦,还有:您可以忽略@Boltz0r的要点。正如@mu所说,它试图解决不同的问题。

0

尝试一下

class ChangeTimeInMsInMyObjectTimes < ActiveRecord::Migration
  def change
    remove_column :my_object_times, :time_in_ms, :your_current_type
    add_column :my_object_times, :time_in_ms, :interval
  end
end

这将删除包含数据的列,如果您需要保留数据,请参见已接受的答案 https://dev59.com/6pffa4cB1Zd3GeqP9o1M#37578835 - Edgar Ortega

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接