淺談Ruby on Rails下的rake與資料庫資料移轉操作_ruby專題

來源:互聯網
上載者:User

不知道你有沒有把資料移轉寫入Migration檔案的經曆,相信無論是老鳥還是新手都這樣幹過吧。事實上,這樣做並不是行不通,只不過這樣的實踐慢慢會給你引入一些不必要的麻煩。

一般認為db/migrate檔案夾裡的內容是關於你資料庫Schema的演變過程,每個新的開發或線上環境都要通過這些Migration來構建可用的資料庫。但如果這裡裝入了,負責細節的業務代碼,比如一些曆史遺留資料的遷移代碼之類的,當一段時間後,資料庫的結構變化了,但Migration沒有跟著變化,漸漸的曾經的輔助代碼,就成了垃圾代碼,不僅不能幫忙構建環境,還會讓rake db:migrate的執行過程異常中斷,無形中增加了新環境的構建成本。

所以正確的做法應該是,Migration只負責Schema相關的事宜,而不該過問資料的細節,具體的資料細節,全部交由rake任務來做,並且這些rake任務也不是一成不變的,隨著時間的推移它們也會廢棄掉,但因為它們與系統的其它部分不想管,所以直接刪掉即可。不過使用Rake做資料移轉也是有講究的,具體如下:

Bad Rake Task

# lib/tasks/temporary/users.rakenamespace :users do task :set_newsletter => :environment do  User.all.each do |user|   if user.confirmed?    user.receive_newsletter = true    user.save   end  end endend

任務會遍曆所有使用者,想想如果資料集很大會怎樣
通過ActiveRecord更新資料,會觸發模型中的驗證和建立回調方法
通過if條件陳述式來判斷是否需要更新資料
不能直觀的看出這個任務是幹什麼的,沒有一個desc,所以也無法通過rake -T找到它
Good Rake Task

# lib/tasks/temporary/users.rakenamespace :users do desc "Update confirmed users to receive newsletter" task set_newsletter: :environment do  users = User.confirmed  puts "Going to update #{users.count} users"  ActiveRecord::Base.transaction do   users.each do |user|    user.mark_newsletter_received!    print "."   end  end  puts " All done now!" endend

通過desc我們可以清楚的知道任務的意圖,並且它也會顯示在rake -T中
通過scope解決了if語句的問題
引入了計數器,以及執行狀態顯示,能讓我們瞭解到程式運行時的情況
把資料的更改放到了事務中執行,可以文法因為資料異常,奔潰導致的不一致問題
最後要補充說明的一點是,有時候,可能直接用SQL語句更簡單有效,特別是在資料集比較大的情況下,一條SQL能幫你省去不少無謂的迴圈!另外,記得上開發環境之前,最好預先檢測一下Rake任務的有效性。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.