2013-03-07 44 views
1

我試圖創建在軌新的rake任務3.Rails的Rake任務 - 解析CSV文件並導入,如果它不存在

我有兩個的CSV文件(gas.csv & elec.csv ),其中使用數據每隔15分鐘從SQL數據庫更新一次。 的CSV的是如下的格式(我沒有在這個控制):

MeterID,RoundedTimeStamp,Value,Register 
165,31/01/2012 00:00,1200,0 
165,28/02/2012 00:15,1201,0 
165,31/03/2012 00:30,1199,0 

的更新用新值按月CSV,我想寫一耙導入任務導入將文件轉換爲模型的相關部分,用法(月,電,氣)。到目前爲止,我已經得到了ELEC進口,這是不是真的工作如下:

require 'csv' 
desc "Importing Usage data from CSV file" 
task import: :environment do 

    file = ".../elec.csv" 

    CSV.foreach(file, headers: true) do |row| 
      Usage.find_or_create_by_month({ 
       month: row[1], 
       elec: row[2] 
      }) 
    end 
end 

當我運行耙:從控制檯的進口,它進口的ELEC使用數據就好了,但不跳過重複。有沒有辦法可以導入這個文件沒有重複,也是一種方法來做同樣的氣體數據?

注意:我知道最好使用first_or_create而不是find_or_create,但這對_by_month不起作用。

乾杯!

+0

'那裏(月:行[1])。first_or_create',find_or_create應爲Rails棄用methos名單上4. – Leito 2013-03-07 18:04:02

+0

是的,我在APIdock上看到了,我是這麼說的,但它也沒用! – KevL 2013-03-07 20:01:10

回答

2
User.where(month: row[1]).first_or_create do |user| 
    user.elec = row[2] 
end 

更多信息以http://apidock.com/rails/ActiveRecord/Relation/first_or_create

+0

這似乎並不奏效 - 即使它們已經存在,它也會創建新記錄(與我自己的功能非常相似)。 – KevL 2013-03-07 20:00:43

+1

@KevL,你是否自己嘗試過?我試着在控制檯上運行,就像提供的示例一樣。我建議你將問題降到最低,並查看失敗的地方。 – Leito 2013-03-07 20:05:35

+0

啊 - 我知道我哪裏出錯了。 RoundedTimeStamp採用日期時間格式,而我的月份列採用日期格式,因此我通過添加'month:row [1] .to_date)'來修復它。謝謝!你知道使用'usage.elec = row [2]',還是把它作爲'.first_or_create(elec:row [2])'這樣做會更快嗎? – KevL 2013-03-07 20:09:54

1

你可以嘗試Upsert

require 'upsert' 
require 'active_support/core_ext' # you'll already have this in Rails 
# ... 
u = Upsert.new Usage.connection, Usage.table_name 
# ... 
CSV.foreach('elec.csv', headers: :first_row) do |row| 
    date = Date.parse row['RoundedTimeStamp'] 
    selector = { meter_id: row['MeterID'], month: date.strftime('%Y-%m') } 
    setter = { elec: row['Value'] } 
    u.row selector, setter 
end 
CSV.foreach('gas.csv', headers: :first_row) do |row| 
    date = Date.parse row['RoundedTimeStamp'] 
    selector = { meter_id: row['MeterID'], month: date.strftime('%Y-%m') } 
    setter = { gas: row['Value'] } 
    u.row selector, setter 
end 

如果您的 「月」 列是一個字符串字段,那麼這將正常工作。如果它是一個真正的日期字段,那麼你可以嘗試只使用第一每月的:

date.strftime('%Y-%m-01') 
+0

我收到一個錯誤,「無法加載這樣的文件 - upsert」?另外,是的,我相當肯定我對這一行是正確的,因爲標題是「RoundedTimeStamp」。 – KevL 2013-03-07 20:06:41

+0

添加「upsert」到您的Gemfile? – 2013-03-07 20:58:27

+0

哎呀...相當明顯!任何想法我怎麼能做到這一點,導入現有的幾個月的氣體也?? – KevL 2013-03-08 16:18:00