1

Rails 3 で新しい rake タスクを作成しようとしています。

SQL データベースから 15 分ごとに更新される使用状況データを含む 2 つの csv ファイル (gas.csv & elec.csv) があります。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 は新しい値で毎月更新されます。モデルの関連部分である使用法 (月、電気、ガス) にファイルをインポートするための rake インポート タスクを作成したいと考えています。これまでのところ、実際には機能していない 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

コンソールから rake:import を実行すると、elec の使用状況データは正常にインポートされますが、重複はスキップされません。このファイルを重複せずにインポートする方法と、ガス データに対して同じことを行う方法はありますか?

注: find_or_create よりも first_or_create を使用する方が良い方法であることはわかっていますが、これは _by_month では機能しません。

乾杯!

4

2 に答える 2

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をご覧ください。

于 2013-03-07T18:07:29.870 に答える
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

「月」列が文字列フィールドの場合、これは機能します。実際の日付フィールドの場合は、毎月1日だけを使用してみてください。

date.strftime('%Y-%m-01')
于 2013-03-07T18:22:32.510 に答える