【问题标题】:FasterCSV tutorial to import data to database?FasterCSV 教程将数据导入数据库?
【发布时间】:2011-09-08 11:22:52
【问题描述】:

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

具体步骤如下:

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

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

谢谢!

【问题讨论】:

  • 谢谢,已经看到了。不幸的是,它没有解决我上面提到的步骤 2 或 3。我也不需要一个工具来进行一次性导入,而是将其构建到应用程序中以让用户导入数据。
  • 到目前为止你写了什么代码?

标签: mysql ruby sqlite import fastercsv


【解决方案1】:

因此,从 Ruby 1.9 开始,FasterCSV 现在似乎是 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 来将条目保存到数据库中。

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

【讨论】:

    【解决方案2】:

    首先,从其他 Stack Overflow 答案开始:Best way to read CSV in Ruby. FasterCSV?

    在开始编写代码之前,我会检查是否有现有的工具来执行导入。你可能想看看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
    

    【讨论】:

      【解决方案3】:

      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 解决方案来简化导入方面的事情。

      【讨论】:

      • 我得试一试。你是对的,它是在给一般用户找麻烦,但我的用户很少,而且他们本身就是开发人员,所以它在设计时就考虑到了这一点。
      【解决方案4】:

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

      CSV.foreach(filename, {:headers => true}) do |row|
        post = Post.find_or_create_by_id row["id"]
        post.update_attributes row.to_hash
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-21
        • 2010-11-06
        • 2011-06-24
        • 2018-02-05
        • 1970-01-01
        • 1970-01-01
        • 2012-08-20
        • 1970-01-01
        相关资源
        最近更新 更多