如何在不丢弃db

时间:2016-02-16 21:18:45

标签: ruby-on-rails ruby

我有一个名为'deliveries'的表,我已通过rake db:migrate迁移,如下所示:

我错误地命名了我的表,并希望学习最有效的方法来将列交付时间(当前在表中定义为t.integer)更改为t.datetime。

class CreateDeliveries < ActiveRecord::Migration
  def change
    create_table :deliveries do |t|
      t.string :name
      t.string :deliveryaddress
      t.integer :deliverytime
      t.string :notes
      t.references :orders, index: true, foreign_key: true

      t.timestamps null: false
    end
  end
end

以下是更多上下文的架构:

 create_table "deliveries", force: :cascade do |t|
   t.string   "name"
   t.string   "deliveryaddress"
   t.integer  "deliverytime"
   t.string   "notes"
   t.integer  "order_id"
   t.datetime "created_at",      null: false
   t.datetime "updated_at",      null: false
end

  add_index "deliveries", ["order_id"], name: "index_deliveries_on_order_id"

  create_table "orders", force: :cascade do |t|
    t.datetime "date"
    t.string   "name"
    t.string   "pickup"
    t.datetime "pickuptime"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
 end

在不丢弃表的情况下执行此操作的最有效方法是什么(之前尝试过此操作只会导致大量的db迁移错误)?谢谢。

**接下来,我进入命令行并输入rails g migration ChangeColumnDeliveryTime。我的db / migrate文件夹中没有生成新文件,这让我感到困惑。所以我必须进入命令行并找到它的相应名称,20160211115009_rename_order_ids_column.rb

接下来我包括以下内容:

 class ChangeColumnDeliveryTime < ActiveRecord::Migration
    def change
    change_column(:deliveries, :deliverytime, :datetime)
  end
end

然后,我运行了rake db:migrate。即使重新启动rails服务器,我也没有在本地环境中看到对列的更新更改。

导致此最新问题的原因是什么?

3 个答案:

答案 0 :(得分:3)

使用与add_column相同的参数将列更改为其他类型。

change_column(table_name, column_name, type, options)

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

答案 1 :(得分:3)

它不适合你,因为你不能将整数迁移到datetime,因为DB服务器不知道如何投射它。

我可以建议你这两种方式:

  • 将当前列从deliverytime重命名为deliverytime_temp
  • 使用日期时间类型
  • 创建名为deliverytime的新列
  • 使用具有铸币值的铸造值更新所有行
  • 删除deliverytime_temp列

这是代码段:

class ChangeColumnDeliveryTime < ActiveRecord::Migration
  def change
    rename_column(:deliveries, :deliverytime, :deliverytime_temp)
    add_column(:deliveries, :deliverytime, :datetime)  
  end
end

数据迁移:

class MigrateDeliveryTimeDates < ActiveRecord::Migration
  class Delivery < ActiveRecord::Base
  end

  def up
    Delivery.reset_column_information

    Delivery.find_each do |delivery|
      delivery.update_column(:deliverytime,  Time.at(delivery.deliverytime_temp))
    end
  end        
end

或者你可以尝试其他方式并找到一种方法来改变使用强制转换的列(to_timestamp + ALTER [ COLUMN ] column [ SET DATA ] TYPE type [ USING expression ] 可能有用。

但是,如果它是相当新的数据库 - 请使用第一个解决方案

答案 2 :(得分:0)

你可以试试change_column http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_column

或remove_column,后跟同一迁移中的add_column。

您不应该放弃桌面,但我不知道这样做会如何影响您的迁移。如果您仍然遇到问题,可以发布完整的架构。