如何更改 Heroku 中的列类型?
Posted
技术标签:
【中文标题】如何更改 Heroku 中的列类型?【英文标题】:How do I change column type in Heroku? 【发布时间】:2011-03-05 19:00:00 【问题描述】:我正在尝试将 db:migrations 耙入我的 heorku 实例中,但出现错误。常见问题解答将我的错误描述如下:
无法更改列类型
示例:PGError: ERROR: column “verified_at”不能转换为类型 “日期”
原因:PostgreSQL 不知道怎么做 将该表中的所有行转换为 指定类型。很可能意味着 你有一个整数或字符串 那个专栏。
解决方案:检查您的记录并 确保它们可以转换为 新型。有时更容易 只是避免使用change_column, 重命名/创建新列 而是。
我现在如何更改此迁移。这是我遇到的问题。对于我的联系人表,我创建了以下内容:
t.string :date_entered
在以后的迁移中,我执行以下操作:
change_column :contacts, :date_entered, :date
这个 change_column 似乎是问题所在。
我应该...手动更改迁移吗?有没有办法可以清理表中的数据(我不知道 Heroku 会识别表中的数据,因为我正在做 rake)。
我显然需要更改这个值,它在我的整个应用程序中都会用到。谢谢。
这就是我正在尝试的……想法?
def self.up
#change_column :contacts, :date_entered, :date
#this fails in postgres, so trying the same outcome
rename_column :contacts, :date_entered, :date_entered_old
add_column :contacts, :date_entered, :date
remove_column :contacts, :date_entered_old
end
def self.down
add_column :contacts, :date_entered_old
remove_column :contacts, :date_entered
rename_column :contacts, :date_entered_old, :date_entered
end
【问题讨论】:
【参考方案1】:执行以下操作:
-
重命名A列
将新列 B 创建为日期
将数据从 A 移动到 B
删除 A
换句话说
def self.up
rename_column :contacts, :date_entered, :date_entered_string
add_column :contacts, :date_entered, :date
Contact.reset_column_information
Contact.find_each |c| c.update_attribute(:date_entered, c.date_entered_string)
remove_column :contacts, :date_entered_string
end
【讨论】:
+1 表示#reset_column_information,这是我以前从未见过的。这看起来在非常罕见的时候会派上用场。 如果您有大量数据,update_attribute 循环可能需要很长时间。运行这个一次性完成的原始 sql 语句要快得多。ActiveRecord::Base.connection.execute("update table set new_column =old_column");
如果旧值需要强制转换也没问题,请在更新调用中使用 postgres 强制转换。【参考方案2】:
这是 Simone Carletti 解决方案的修改和测试版本
class ModifyContacts < ActiveRecord::Migration
def self.up
rename_column :contacts, :date_entered, :date_entered_string
add_column :contacts, :date_entered, :date
Contact.reset_column_information
Contact.find(:all).each |contact| contact.update_attribute(:date_entered, contact.date_entered_string)
remove_column :contacts, :date_entered_string
end
end
【讨论】:
你确实想要那个find_each
。您的版本会将整个表读入内存,而 find_each 会同时获取一些行数。以上是关于如何更改 Heroku 中的列类型?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不包含新列名和类型的情况下更改现有 Hive 表中的列注释?