2011-12-20 100 views
25

有人可以給我一個簡短的介紹,使用Mongoid在Rails中進行數據庫遷移?我特別感興趣的是每次文檔遷移的懶惰。通過這個,我的意思是說,只要你從數據庫中讀取一個文檔,就會將它遷移到最新版本並再次保存。管理mongoid遷移

有沒有人做過這種事情?我遇到過mongoid_rails_migrations,但它沒有提供任何形式的文檔,雖然看起來像這樣,但我不確定如何使用它。

我應該指出我只是在概念上熟悉ActiveRecord遷移。

+0

我不認爲懶惰遷移是一個好主意。我寧願花時間運行大規模的數據更新,等待它完成,監視,考慮如果出現任何問題時恢復的方法,並首先在數據庫克隆上進行測試。這需要時間,但不會讓數據不一致。 – 2013-02-22 10:57:29

回答

21

如果您想一次執行整個遷移,那麼mongoid_rails_migrations將執行您所需的操作。沒有太多需要記錄的東西,它重複了標準ActiveRecord遷移的功能。你寫你的遷移,然後你使用rake db:migrate來應用它們,它處理找出哪些已經和沒有被運行。如果您想了解某些具體內容,我可以回答更多問題。

對於惰性遷移,最簡單的解決方案是使用after_initialize回調。檢查字段中的舊數據計劃相匹配,如果確實如此,你修改的對象和更新,因此,例如:

class Person 
    include Mongoid::Document 

    after_initialize :migrate_data 

    field :name, :type => String 

    def migrate_data 
     if !self[:first_name].blank? or !self[:last_name].blank? 
      self.set(:name, "#{self[:first_name]} #{self[:last_name]}".strip) 
      self.remove_attribute(:first_name) 
      self.remove_attribute(:last_name) 
     end 
    end 
end 

的權衡牢記與我上面給了具體做法:

如果您運行的請求返回很多記錄,例如Person.all.each {|p| puts p.name}和100人擁有舊格式,則會立即運行100個設置的查詢。您也可以撥打self.name = "#{self.first_name} #{self.last_name}".strip,但這意味着只有保存記錄時纔會遷移您的數據。

您可能遇到的一般問題是,在遷移所有數據之前,任何批量查詢(如Person.where(:name => /Foo/).count)都將失敗。此外,如果您執行Person.only(:name).first遷移將失敗,因爲您忘記了包含first_namelast_name字段。