Ruby-on-rails 如何通过 rake 任务导入 CSV 文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12461260/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:46:21  来源:igfitidea点击:

How can I import a CSV file via a rake task?

ruby-on-railsrakeimport-from-csv

提问by RubyDude1012

I know this question has been asked a lot on this forum but I'm under a strict deadline and I need some help, so any advice is much appreciated. I'm new to Ruby on Rails so please keep that in mind when responding. I want to create a rake task that, when run, updates multiple tables in mysqlite db. This is a migration file that creates a new incident in my db. How do I create a rake task that will input all this info via a CSV file. Can someone PLEASE give me some help in writing the rake file from start to finish. Obviously you don't need to write every task for every string, just give me a few examples. And besides the actual rake file, do I need to add code to any other part of my app (I know thats a very general question, but if I do need to add code, I would appreciate a general description of where). I feel a little bit of guidance will go along way. If anyone needs any more information from me please just ask.

我知道这个问题在这个论坛上被问到了很多,但我有一个严格的截止日期,我需要一些帮助,所以非常感谢任何建议。我是 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

采纳答案by Rubyman

under your project folder in lib/task create a rake file say "import_incidents_csv.rake"

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

follow this Ruby on Rails - Import Data from a CSV file

按照这个 Ruby on Rails - 从 CSV 文件导入数据

in rake file have following code

在 rake 文件中有以下代码

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

You can call this task as "rake import_incidents_csv:create_incidents"

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

回答by lflores

I worked on this for hours and hours one day. I finally got it to work by doing the following:

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

  1. Added a header in the first row to my csv file that reflected the attr_accessiblein my model. In my case my model was attr_accessible:intro, :nameand in my csv file the first line read name, intro.
  2. Created a custom rake file. I named mine import.rake and placed it in the lib/tasks folder. Place this code in that file:
  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
#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

Then type bundle exec rake importinto the command line.

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

To get this to work I had quite SQLite Database Browser. I hope that helps someone!

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

回答by Angelo Chrysoulakis

Here is an example CSV that I imported using rake db:seed. I wrote this into the seeds.rb file and put the CSV file into /public/seed_data/zip_code.csv. It's pretty self explanatory (i.e., the csv has three columns: code, long. and lat.

这是我使用 rake db:seed 导入的示例 CSV。我将其写入seeds.rb 文件并将CSV 文件放入/public/seed_data/zip_code.csv。这是非常不言自明的(即,csv 有三列:code、long. 和 lat。

The code parses each line, extracts the pertinent data and assigns it to a local variable then writes it to a record. Hope it helps.

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

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

回答by RAJ

You can read your csv file using CSVmodule of rails and can create records. Here is detailed help: Populate db using csv

您可以使用CSVrails 模块读取您的 csv 文件并可以创建记录。这是详细的帮助:使用 csv 填充数据库

回答by ebilly

I've used this one in the past. It takes any type of model.

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

rake csv_model_import[bunnies.csv,Bunny]

耙 csv_model_import[bunnies.csv,Bunny]

Works like a charm.

奇迹般有效。

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