2

有谁知道任何教程演示如何使用 FasterCSV 在 Ruby 应用程序中导入数据并将其保存到 SQLite 或 MySQL 数据库?

以下是涉及的具体步骤:

  1. 逐行读取文件(该.foreach方法根据文档执行此操作)
  2. 将文件中的标题名称映射到数据库列名称
  3. 在数据库中为 CSV 数据创建条目(似乎可以在一个块.new中使用).save.foreach

这是一个基本的使用场景,但我找不到任何教程,所以任何资源都会有所帮助。

谢谢!

4

4 回答 4

2

所以看起来 FasterCSV 现在是 Ruby 1.9 的 Ruby 核心的一部分,所以这就是我最终要做的,以实现上述问题中的目标:

@importedfile = Import.find(params[:id])
filename = @importedfile.csv.path
CSV.foreach(filename, {:headers => true}) do |row|
  @post = Post.find_or_create_by_email(
    :content          =>  row[0],
    :name             =>  row[1],
    :blog_url         =>  row[2],
    :email            =>  row[3]
  )
end
flash[:notice] = "New posts were successfully processed."
redirect_to posts_path

函数内部find_or_create_by_email是从数据库列到 CSV 文件列的映射:row[0], row[1], row[2], row[3].

因为它是一个find_or_create函数,所以我不需要显式调用@post.save来将条目保存到数据库中。

如果有更好的方法,请更新或添加您自己的答案。

于 2011-06-05T15:29:58.503 回答
0

首先,从其他 Stack Overflow 答案开始:Best way to read CSV in Ruby。更快的CSV?

在开始编写代码之前,我会检查是否有现有的工具来进行导入。您可能想查看mysqlimport

这是一个简单的示例,展示了如何将 CSV 标头映射到数据库的列:

require "csv"

data = <<EOT
header1, header2, header 3
1, 2, 3
2, 2, 3
3, 2, 3
EOT

header_to_table_columns = {
  'header1'  => 'col1',
  'header2'  => 'col2',
  'header 3' => 'col3'
}

arr_of_arrs = CSV.parse(data)
headers = arr_of_arrs.shift.map{ |i| i.strip }
db_cols = header_to_table_columns.values_at(*headers)
arr_of_arrs.each do |ary|
  # insert into the database using an ORM or by creating insert statements
end
于 2011-06-04T18:20:51.977 回答
0

Ruby 非常适合滚动您自己的导入例程。

  1. 读取文件(方便的块结构以确保正确关闭文件句柄):

    File.open( filepath ) do |f|
      f.each_line do |line|
        do something with the line...
      end
    end
    
  2. 将标题名称映射到列(您可能需要检查匹配的数组长度):

    Hash[header_array.zip( line_array )]
    
  3. 使用 activerecord 在数据库中创建条目:

    SomeModel.create( Hash[header_array.zip( line_array )] )
    

听起来您打算让用户上传 csv 文件并将它们导入数据库。除非他们精通数据,否则这是自找麻烦。您可能想研究一个 nosql 解决方案来简化导入方面的事情。

于 2011-06-05T16:57:48.133 回答
0

如果您可以使用 ID 来识别记录并且不需要列名映射,这似乎是最短的方法:

CSV.foreach(filename, {:headers => true}) do |row|
  post = Post.find_or_create_by_id row["id"]
  post.update_attributes row.to_hash
end
于 2012-07-13T13:56:31.790 回答