有谁知道任何教程演示如何使用 FasterCSV 在 Ruby 应用程序中导入数据并将其保存到 SQLite 或 MySQL 数据库?
以下是涉及的具体步骤:
- 逐行读取文件(该
.foreach
方法根据文档执行此操作) - 将文件中的标题名称映射到数据库列名称
- 在数据库中为 CSV 数据创建条目(似乎可以在一个块
.new
中使用).save
.foreach
这是一个基本的使用场景,但我找不到任何教程,所以任何资源都会有所帮助。
谢谢!
所以看起来 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
来将条目保存到数据库中。
如果有更好的方法,请更新或添加您自己的答案。
首先,从其他 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
Ruby 非常适合滚动您自己的导入例程。
读取文件(方便的块结构以确保正确关闭文件句柄):
File.open( filepath ) do |f|
f.each_line do |line|
do something with the line...
end
end
将标题名称映射到列(您可能需要检查匹配的数组长度):
Hash[header_array.zip( line_array )]
使用 activerecord 在数据库中创建条目:
SomeModel.create( Hash[header_array.zip( line_array )] )
听起来您打算让用户上传 csv 文件并将它们导入数据库。除非他们精通数据,否则这是自找麻烦。您可能想研究一个 nosql 解决方案来简化导入方面的事情。
如果您可以使用 ID 来识别记录并且不需要列名映射,这似乎是最短的方法:
CSV.foreach(filename, {:headers => true}) do |row|
post = Post.find_or_create_by_id row["id"]
post.update_attributes row.to_hash
end