Ruby on rails 如何更改Heroku中的列类型?

Ruby on rails 如何更改Heroku中的列类型?,ruby-on-rails,ruby,database,postgresql,heroku,Ruby On Rails,Ruby,Database,Postgresql,Heroku,我试图将db:migrations耙入我的heorku实例,但我得到了一个错误。常见问题解答将我的错误描述如下: 无法更改列类型 示例:PGError:ERROR:column 无法将“已验证的位置”转换为类型 “日期” 原因:PostgreSQL不知道如何 将该表中的所有行强制转换为 指定的类型。很可能这意味着 您有一个整数或字符串 那个专栏 解决方案:检查您的记录和 确保它们可以转换为 新型。有时候更容易理解 只需避免使用“更改”列, 重命名/创建新列 相反 现在如何更改此迁移。这就是我的问

我试图将db:migrations耙入我的heorku实例,但我得到了一个错误。常见问题解答将我的错误描述如下:

无法更改列类型

示例:PGError:ERROR:column 无法将“已验证的位置”转换为类型 “日期”

原因:PostgreSQL不知道如何 将该表中的所有行强制转换为 指定的类型。很可能这意味着 您有一个整数或字符串 那个专栏

解决方案:检查您的记录和 确保它们可以转换为 新型。有时候更容易理解 只需避免使用“更改”列, 重命名/创建新列 相反

现在如何更改此迁移。这就是我的问题。对于我的联系人表,我创建了以下内容:

  t.string :date_entered
 change_column :contacts, :date_entered, :date
在以后的迁移中,我将执行以下操作:

  t.string :date_entered
 change_column :contacts, :date_entered, :date
“更改”列似乎是问题所在

我应该…用手改变那个迁移吗?是否有一种方法可以清除表中的数据(我不知道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
请执行以下操作:

  t.string :date_entered
 change_column :contacts, :date_entered, :date
  • 将列重命名为A
  • 创建新列B作为日期
  • 将数据从A移到B
  • 移走
  • 换句话说

    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
    

    这是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
    
    class ModifyContacts
    +1用于“重置列”信息,这是我以前从未见过的。这看起来在极少数需要的时候非常方便。如果你有很多数据,更新属性循环可能需要很长时间。运行一次完成所有任务的原始sql语句要快得多<代码>ActiveRecord::Base.connection.execute(“更新表设置新列=旧列”)如果旧值需要强制转换也没有问题,请在更新调用中使用postgres强制转换。不过,您确实希望
    找到每个值。您的版本将把整个表读入内存,而find_每个表将同时获得一些行数。