【问题标题】:How can I import a CSV file via a rake task?如何通过 rake 任务导入 CSV 文件?
【发布时间】:2012-09-09 18:53:54
【问题描述】:

我知道这个问题在这个论坛上被问了很多,但是我在一个严格的截止日期之前,我需要一些帮助,所以非常感谢任何建议。我是 Ruby on Rails 的新手,所以在回复时请记住这一点。我想创建一个 rake 任务,它在运行时会更新 mysqlite db 中的多个表。这是一个迁移文件,它在我的数据库中创建了一个新事件。如何创建将通过 CSV 文件输入所有这些信息的 rake 任务。有人可以帮助我从头到尾编写 rake 文件吗?显然您不需要为每个字符串编写每个任务,只需举几个例子。除了实际的 rake 文件之外,我是否需要将代码添加到我的应用程序的任何其他部分(我知道这是一个非常普遍的问题,但如果我确实需要添加代码,我会很感激对位置的一般描述)。我觉得会有一点指导。如果有人需要我提供更多信息,请询问。

class CreateIncidents < ActiveRecord::Migration
  def self.up
    create_table :incidents do |t|
      t.datetime :incident_datetime
      t.string :location
      t.string :report_nr
      t.string :responsible_party
      t.string :area_resident
      t.string :street
      t.string :city
      t.string :state
      t.string :home_phone
      t.string :cell_phone
      t.string :insurance_carrier_name
      t.string :insurance_carrier_street
      t.string :insurance_carrier_city
      t.string :insurance_carrier_state
      t.string :insurance_carrier_phone
      t.string :insurance_carrier_contact
      t.string :policy_nr
      t.string :vin_nr
      t.string :license_nr
      t.string :vehicle_make
      t.string :vehicle_model
      t.string :vehicle_year


      t.timestamps
    end
  end

  def self.down
    drop_table :incidents
  end
end

【问题讨论】:

标签: ruby-on-rails rake import-from-csv


【解决方案1】:

在 lib/task 中的项目文件夹下创建一个 rake 文件,例如“import_incidents_csv.rake”

关注这个 Ruby on Rails - Import Data from a CSV file

在 rake 文件中有以下代码

require 'csv'
namespace :import_incidents_csv do
  task :create_incidents => :environment do
    "code from the link"  
  end
end 

您可以将此任务称为“rake import_incidents_csv:create_incidents”

【讨论】:

  • 我的问题是我不知道要放入 rake 文件中的代码,该代码可以正确创建新事件而没有任何错误。但感谢您的回复。
  • 您需要创建一个 csv 文件,其中第一行作为事件表的列名。
  • 这是我在 StackOverflow 上找到的代码,我试图适应我的应用程序。我在将其格式化为读取时遇到问题...抱歉 desc “单行任务描述”任务:import_csv 确实需要 'csv' csv_text = File.read('c:/rails/thumb/incidents.csv') csv = CSV.parse(csv_text, :headers => true) csv.each 做 |row| row = row.to_hash.with_indifferent_access Incidents.create!(row.to_hash.symbolize_keys) end end
  • 我得到的第一个错误是未定义的方法'with_indifferent_access'。所以我删除了它,现在我得到了未初始化的常量 Object::Incidents。我正在导入的 csv 文件是对我使用 SQLite Manager 导出的事件报告的修改。我删除了所有以前的事件并输入了一个虚拟事件。我使用逗号分隔符导出它,并确保它的第一行标识为列名。我是否走在正确的轨道上??
  • 感谢 Rubyman 的帮助,但我还有一些问题(一些新手问题)。在您放置“来自链接的代码”的地方,我添加了我在原始问题中发布的所有代码。我不确定这是否是你的意思。当我运行您指定的 rake 命令时,它可以正常工作,但没有添加事件。我没有在这个过程中指定 rake 文件应该在哪里查找 csv 文件,这一定是问题所在。我在哪里放置 csv 文件或在哪里指定路径?谢谢
【解决方案2】:

我一天为此工作了好几个小时。我终于通过执行以下操作使其工作:

  1. 在我的 csv 文件的第一行添加了一个标题,它反映了我模型中的 attr_accessible。在我的例子中,我的模型是attr_accessible:intro:name,在我的 csv 文件中,第一行读取名称,介绍。
  2. 创建了一个自定义 rake 文件。我命名了我的 import.rake 并将其放在 lib/tasks 文件夹中。将此代码放在该文件中:
#lib/tasks/import.rake
require 'csv'
desc "Imports a CSV file into an ActiveRecord table"
task :import, [:filename] => :environment do    
    CSV.foreach('myfile.csv', :headers => true) do |row|
      MyModel.create!(row.to_hash)
    end
end

然后在命令行中输入bundle exec rake import

为了让它工作,我有相当多的 SQLite 数据库浏览器。我希望对某人有所帮助!

【讨论】:

    【解决方案3】:

    这是我使用 rake db:seed 导入的示例 CSV。我把它写到了seeds.rb 文件中,然后把CSV 文件放到了/public/seed_data/zip_code.csv 中。这很不言自明(即 csv 有三列:代码、长列和纬度。

    代码解析每一行,提取相关数据并将其分配给局部变量,然后将其写入记录。希望对您有所帮助。

    File.open("#{Rails.root}/public/seed_data/zip_code.csv") do |zip_codes|
      zip_codes.read.each_line do |zip_code|
        code, longitude, latitude = zip_code.chomp.split(",")
        #  to remove the quotes from the csv text:
        code.gsub!(/\A"|"\Z/, '')
        # to create each record in the database
        ZipCodeGeo.create!(:zip_code => code, :longitude => longitude, :latitude =>      latitude)             
      end
    end
    

    【讨论】:

      【解决方案4】:

      您可以使用 rails 的 CSV 模块读取您的 csv 文件并创建记录。这里有详细的帮助:Populate db using csv

      【讨论】:

        【解决方案5】:

        我以前用过这个。它需要任何类型的模型。

        rake csv_model_import[bunnies.csv,Bunny]

        像魅力一样工作。

        desc "Imports a CSV file into an ActiveRecord table"
        task :csv_model_import, :filename, :model, :needs => :environment do |task,args|
          lines = File.new(args[:filename]).readlines
          header = lines.shift.strip
          keys = header.split(',')
          lines.each do |line|
            params = {}
            values = line.strip.split(',')
            keys.each_with_index do |key,i|
              params[key] = values[i]
            end
            Module.const_get(args[:model]).create(params)
          end
        end

        【讨论】:

        • 坏样本,因为逗号
        猜你喜欢
        • 2016-09-16
        • 2017-05-03
        • 1970-01-01
        • 2014-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多