2010-07-27 33 views
9

目標:使用CRON任務(或其他預定事件)通過夜間從現有系統導出數據來更新數據庫。如何編寫Rake任務以將數據導入Rails應用程序?

在現有系統中創建/更新/刪除所有數據。該網站不直接與此係統集成,因此rails應用程序只需反映出現在數據導出中的更新。

我有一個.txt文件〜5000的產品,看起來像這樣:

"1234":"product name":"attr 1":"attr 2":"ABC Manufacturing":"2222" 
"A134":"another product":"attr 1":"attr 2":"Foobar World":"2447" 
... 

所有值都包含在由冒號(:

字段是分開的雙引號(")字符串:

  • id:unique id;字母數字
  • name:產品名稱;任何字符
  • 屬性列:字符串;任何字符(例如,尺寸,重量,顏色,尺寸)
  • vendor_name:string;任何字符
  • vendor_id:唯一的供應商ID;數字

當前系統中的供應商信息未標準化。

這裏有什麼最佳實踐?是否可以刪除產品和供應商表格並在每個週期用新數據重寫?或者只添加新行並更新現有行更好?

注:

  1. 這些數據將被用來生成Orders將通過夜間數據庫進口持續。 OrderItems將需要連接到數據文件中指定的產品id,因此我們不能依賴於自動遞增主鍵對於每個導入都是相同的;需要使用唯一的字母數字ID加入productsorder_items
  2. 理想情況下,我想進口商正常化賣方數據
  3. 我不能用香草的SQL語句,所以我想我需要爲了使用Product.create(...)Vendor.create(...)風格的語法來寫rake任務。
  4. 這將在EngineYard的

回答

14

我不會刪除該產品和廠商在每個循環表來實現。這是一個軌道應用程序?如果是這樣,有一些非常好的ActiveRecord助手可以爲你派上用場。

如果你有一個產品的活動記錄模式,可以這樣做:

p = Product.find_or_initialize_by_identifier(<id you get from file>) 
p.name = <name from file> 
p.size = <size from file> 
etc... 
p.save! 

的find_or_initialize將查找該產品由您指定的ID數據庫,如果無法找到它,它會創建一個新的。這樣做非常方便,因爲如果有任何數據發生更改,ActiveRecord將只保存到數據庫,並且它會自動更新表中相應的任何時間戳字段(updated_at)。還有一件事,因爲你會通過標識符(文件中的id)查找記錄,所以我會確保在數據庫的該字段中添加一個索引。

要創建一個rake任務來完成這項工作,我需要將rake文件添加到rails應用程序的lib/tasks目錄中。我們將其稱爲data.rake。

裏面data.rake,它會是這個樣子:

namespace :data do 
    desc "import data from files to database" 
    task :import => :environment do 
    file = File.open(<file to import>) 
    file.each do |line| 
     attrs = line.split(":") 
     p = Product.find_or_initialize_by_identifier(attrs[0]) 
     p.name = attrs[1] 
     etc... 
     p.save! 
    end 
    end 
end 

不是叫耙任務,用「回扣數據:進口」的命令行。

+0

我試過,但我得到的錯誤'未定義的局部變量或方法「數據」主:Object'。任何想法,爲什麼這可能會發生? – Nick 2012-04-13 22:35:43

+0

問題是'命名空間數據'必須改爲'名稱空間:數據操作'。 – Nick 2012-04-16 15:51:20

0

由於產品並沒有真正改變那麼多,所以我會看到的最好的方法是隻更新改變的記錄。

  1. 使用一個SQL語句獲取所有的增量
  2. 大規模更新

如果你有在你的模型標準化代碼,你可以使用Product.create和Vendor.create要不然將只是一個矯枉過正。另外,請考慮在單個SQL事務中插入多個記錄,其速度要快得多。

+0

正如我的問題所述,我__不能使用vanilla SQL語句。 – 2010-07-27 18:29:08

0
  • 創建一個cronned
  • 使用更快的CSV或通過香草紅寶石一樣通過解析行的文件行進口商耙子任務:

file.each做|線| products_array = line.split( 「:」) 結束

  • 分割每行的 「:」 並推到一個哈希
  • 使用find_or_initialize來填充你的數據庫,如:

    Product.find_or_initialize_by_name_and_vendor_id(「富」,111)

+0

你爲什麼使用'find_or_initialize_by_name_and_vendor_id'?這是否表示產品'accep_nested_attributes_for:vendor'? – 2010-07-27 18:52:15

相關問題