ActiveRecord #create不允许设置id

时间:2014-11-13 15:41:53

标签: activerecord mass-assignment

我需要批量插入> 100.000条记录。 数据库不会创建id,我必须使用给定的UUID: 使用mymodel.new分配ID在循环中执行此操作,然后保存记录将起作用但速度太慢(约20分钟)

当我创建一个数组'记录'并使用mymodel.create(记录)我遇到了'无法批量分配id'问题。 我已经尝试了所有可以找到的解决方案:

  • ' attr_acccessible:id,...'对于模型。适用于除了id之外的所有人。
  • (重新)定义' def self.attributes_protected_by_default [] end' - 没效果
  • 一个建议是使用'创建'使用':without_protection => true',但create不会有多个参数。

。所以这些解决方案都没有帮助。 我还能做什么?

1 个答案:

答案 0 :(得分:0)

最后,我发现了一种在Rails方式下可能不优雅的解决方案,但它解决了我的性能问题:

起初我尝试了@Albin建议只发现创建(记录)的速度不快(仍然> 15分钟)。

我现在的解决方案是:

  • 创建临时CSV文件

    db_tmp = File.open("tmp_file", "w")
    records = ""
    @data_records.each do |row|
      records << "#{row['id']},#{row['id']},#{field_1},#{row['field_2']}, ... \n"
    end
    db_tmp.write(records)
    db_tmp.close
    
  • 使用加载数据命令执行sql

    sql = "load data infile 'tmp_file' into table my_table 
      fields optionally enclosed by '\"' terminated by ','
      (id,field_1,field_2, ... )"
    ActiveRecord::Base.connection.execute(sql)
    

整个过程现在持续不到1(!)分钟,包括通过网络获取数据并将原始json消息解析为散列。

我知道这并没有说明如何将创建技巧转化为允许ID分配,但性能问题已经解决。

另一点是我的解决方案绕过了为模型定义的任何验证。这不是问题,因为在这种情况下我知道我可以依赖我收到的数据的完整性 - 如果有问题,加载会失败并且执行会引发异常。