批量插入嵌套模型中的数据

时间:2011-12-13 17:47:06

标签: ruby-on-rails ruby-on-rails-3 activerecord

我一直在关注大量插入数据this fantastic tutorial。一切都很顺利,我的交易时间从大约30秒减少到不到1秒。)

我只是不知道如何填充子模型中的字段:

has_many :check, :dependent => :destroy
accepts_nested_attributes_for :check, :reject_if => lambda { |a| a[:value].blank? },   :allow_destroy => true   

以前,我用过这个:

...
User.create!(:username => username, :check_attributes => [ {:attribute_name => "User-Password", :value => password, :op => ":="}])   
...

由于采用了不同的方法,我现在在我的用户模型中得到了这个:

  def self.activerecord_extensions_mass_insert(validate = true)
        columns = [:username]
        values = []
         10000.times do
           username = ""
           5.times { username << (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr }
           values.push [username]
         end
        User.import columns, values, {:validate => validate}
  end

我尝试过使用这个以及其他一些变化而没有成功......

  columns = [:username, :check_attributes => [ :attribute_name, :value, :op]]

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

导入不会接受嵌套,所以我认为你对这种方法运气不好。 为什么不有两个字符串,user_sql和check_sql,然后在循环时手动为扩展插入构建每个sql语句。然后你可以运行两个查询而不是一堆。 从好的方面来说,你将从多个查询的索引惩罚中节省更多的时间。

编辑添加代码:  你一次构建两个sql语句,这样你就可以通过user_id让它们相互关联,然后在最后你可以执行。如果这些东西可以用于生产,请在事务中包装sql调用,这样你就不会发生任何事故。

user_sql = "INSERT into users (id,username,password) VALUES\n"
check_sql = "INSERT into check_attributes (user_id,foo,bar) VALUES\n"
random_data_pool = [('0'..'9'),('A'..'Z'),('a'..'z')].collect(&:to_a).flatten
max_loop = 10

1.upto(max_loop) do |i|
 seperator = (i == max_loop) ? ';' : ",\n"
 username = (1..5).map{ random_data_pool[Kernel.rand(random_data_pool.size)] }.join
 password = (1..5).map{ random_data_pool[Kernel.rand(random_data_pool.size)] }.join
 user_sql += "(#{i},'#{username}','#{password}')" + seperator
 check_sql +="(#{i},true,'potato')" + seperator
end


ActiveRecord::Base.connection.execute(user_sql)
ActiveRecord::Base.connection.execute(check_sql)