2012-02-22 85 views
1

如何運行遷移以更改Mongoid/MongoDB中字段的類型而不丟失任何數據?更改Mongoid中的字段類型而不丟失數據

在我的情況下,我試圖從BigDecimal(存儲爲字符串)轉換爲Integer來存儲一些錢。我需要將字符串十進制表示轉換爲整數的分。我不想丟失現有的數據。

我假設的步驟可能是這樣的:

  1. 創造新的整型字段用一個新的名字,說amount2
  2. 部署到生產環境和運行遷移(或耙任務),其將每個amountamount2
  3. 正確的價值(這整個過程中現有代碼仍然使用amount並沒有從用戶的角度來看停機)
  4. 採取現場檢修,運行日Ë遷移一個更多的時間來捕捉,可以在最後幾分鐘發生了變化
  5. 刪除amount和重命名amount2amount
  6. 部署新的代碼,預計amount是一個整數
  7. 把網站備份
  8. 任何 amount領域

它看起來像Mongoid提供rename方法:http://mongoid.org/docs/persistence/atomic.html#rename

但我有點困惑這是如何使用的。如果您有一個名爲amount2的字段(並且您已刪除amount),那麼您是否只運行Transaction.rename :amount2, :amount?那麼我想這會立刻破壞底層表示,所以你必須在這之後重新啓動你的應用服務器?如果你運行的話會發生什麼,而amount仍然存在?它會被覆蓋,失敗或嘗試自行轉換嗎?

謝謝!

+0

聽起來合乎邏輯的。但我不確定是否需要重新啓動。首先,你需要更新模型中的字段名稱? 至於重寫,我不知道,但這個鏈接的更新插入部分http://whyjava.wordpress.com/2012/02/07/how-to-rename-field-in-all-the-mongodb -documents /確實似乎暗示它會嘗試寫入,並且可能會覆蓋該字段(如果存在)。所以它不像常規的基於SQL的重命名,而是單獨移動每個文檔值。說得通? – 2012-02-22 06:22:50

+0

嗯...不知道,還是想獲得工作的例子,從開始到結束。如果我的成功,我會發佈一個。 – 2012-02-23 05:03:51

回答

3

好吧,我做到了。我認爲這是使用蒙戈控制檯是這樣一個更快的方法: MongoDB: How to change the type of a field?

但我無法得到的轉換工作,所以選擇了在軌控制檯更多的停機時間這種慢的方式。如果有人有更快的解決方案,請發佈。

  • 創造新的整型字段用一個新的名字,說amount2
  • 互相轉換amount向右值amount2在控制檯或耙任務

Mongoid.identity_map_enabled = false 
Transaction.all.each_with_index do |t,i| 
    puts i if i%1000==0 
    t.amount2 = t.amount.to_money 
    break if !t.save 
end 

請注意.all.each正常工作(您不需要像常規一樣使用.find_each或.find_in_batches由於mongodb遊標,activerecord與mysql)。只要identity_map關閉,它就不會填充內存。

  • 採取現場檢修,運行遷移更多的時間來捕捉,可以在最後幾分鐘已經改變任何金額字段(類似Transaction.where(:updated_at.gt => 1.hour.ago).each_with_index...

  • 註釋掉field :amount, type: BigDecimal在模型中,你不想mongoid瞭解這個領域了,並推動該代碼

  • 現在運行另一個腳本來重命名列(它會覆蓋過程中的任何舊的BigDecimal字符串值)。你可能需要的任何評論您的驗證在期望舊領域的模型上有。

Mongoid.identity_map_enabled = false 
Transaction.all.each_with_index do |t,i| 
    puts i if i%1000==0 
    t.rename :amount2, :amount 
end 

這是原子,並且不需要模型上的節省。

  • 更新模型以反映新的列類型field :amount, type: Integer
  • 部署,並把網站備份

如前所述,我認爲有一個更好的辦法,因此,如果任何人有一些提示,請分享。謝謝!

+0

只是一個問題。任何機會你的光標超時大數據集? – 2012-02-24 00:09:28

+0

是的,我認爲蒙戈的默認光標超時時間爲10分鐘,可發生肯定的。如果你可以斟酌地寫它(檢查amount2是否爲零)並且多次運行,這可能會起作用。絕對看起來比它應該是困難的。 – 2012-08-16 06:08:04

+0

更新,我大概應該用這樣的:https://github.com/nviennot/mongoid_lazy_migration看起來比我做了什麼 – 2012-08-16 06:38:14

相關問題