Ruby on rails Rails rake任务-解析CSV文件并导入(如果不需要)';不存在

Ruby on rails Rails rake任务-解析CSV文件并导入(如果不需要)';不存在,ruby-on-rails,rake,Ruby On Rails,Rake,我正在尝试在rails 3中创建一个新的rake任务 我有两个csv文件(gas.csv和elec.csv),其中包含每十五分钟从SQL数据库更新一次的使用数据。 csv的格式如下(我无法控制): csv每月更新一次新值,我想写一个rake导入任务,将文件导入模型的相关部分,用法(月、电、气)。到目前为止,我已经为elec导入准备了以下内容,但实际上无法正常工作: require 'csv' desc "Importing Usage data from CSV file" task impor

我正在尝试在rails 3中创建一个新的rake任务

我有两个csv文件(gas.csv和elec.csv),其中包含每十五分钟从SQL数据库更新一次的使用数据。 csv的格式如下(我无法控制):

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使用数据,但不会跳过重复的数据。是否有一种方法可以导入此文件而不产生副本,以及对气体数据执行相同操作

注意:我知道使用first_或_create比使用find_或_create更好,但这不适合每个月使用

干杯

User.where(month: row[1]).first_or_create do |user|
  user.elec = row[2]
end
更多信息请访问

您可以尝试:

如果“月”列是一个字符串字段,那么这将起作用。如果它是一个真实的日期字段,那么您可以尝试只使用每个月的第一个:

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

where(month:row[1])。first_或_create
、find_或_create应该在Rails 4不推荐使用的方法列表中。是的,我在APIdock上看到过,我先用这种方法,但它也不起作用!这似乎不起作用-它会创建新记录,即使它们已经存在(功能与我自己的记录大致相同)。@KevL,你自己尝试过吗?我在控制台上进行了尝试,其工作原理与提供的示例相同。我会建议你把问题降到最低限度,看看哪里出了问题。啊,我知道哪里出了问题。RoundedTimeStamp是DateTime格式,my month列是date格式,因此我通过添加
month:row[1]。to_date)
对其进行了修复。谢谢你知道用
usage.elec=row[2]
还是直接用
的方式来做会更快吗?首先\u或\u创建(elec:row[2])
?不,但是如果我设置了一个属性,我会使用不带块的内联版本。对于每个属性,不要重复使用方法或lambda。在处理和执行单个foreach之前,您始终可以将一个文件的内容附加到另一个文件,但这将比需要的更复杂。我收到一个错误,“无法加载这样的文件--upsert”?另外,我相当肯定我对第[1]行的理解是正确的,因为标题是“RoundedTimeStamp”。在Gemfile中添加“upsert”?啊,feck…非常明显!你知道我怎样才能为现有月份导入气体吗?你只需要2个
CSV.foreach
块,每个CSV文件一个。在每一个字段中,只要确保仔细地将选择器设置为“name”字段谢谢,我现在已经尝试了这两段代码,它们不会向数据库添加任何内容(不会抛出错误)。即使我销毁了所有的用法,他们还是什么都不加?以下是我使用的代码:
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')