【问题标题】:How to generate sample records with fewer SQL queries?如何用更少的 SQL 查询生成样本记录?
【发布时间】:2013-10-12 19:44:41
【问题描述】:

在我的 Rails 应用程序的 User 控制器中,我有一个使用示例 people 填充用户数据库的操作:

def generate_samples
  10.times do
    p = current_user.people.create!(:first_name   => Faker::Name.first_name,
                                    :last_name    => Faker::Name.last_name,
                                    :email        => Faker::Internet.email)
    p.sample = true
    p.save
  end
  flash[:success] = "Samples generated."
  redirect_to people_path
end

困扰我的是,生成这 10 个人需要 Rails 83 SQL 查询。

有没有一种方法可以简化我的代码,并且可能只用一个查询创建 X 个用户?

感谢您的帮助。

【问题讨论】:

  • 您需要了解所有常见的 ActiveRecord 内容还是直接使用 SQL? ActiveRecord 在你背后做了很多不适合批量数据加载的事情。
  • @muistooshort:我可以这样做,但我不希望我的 Ruby 文件中有太多原始 SQL。而且我对 SQL 也不是很有经验。更愿意在这里使用 Ruby。
  • 10 个 SQL INSERT 应该很容易,或者一个包含 10 个部分 VALUES 的 INSERT。您需要在数据库中有适当的约束(无论如何您都应该有),并且您必须小心引用或使用低级数据库驱动程序接口,以便您可以在 SQL 中使用真正的占位符。跨度>
  • @muistooshort:我不完全理解我害怕。我还是 Rails 的新手。你能指出任何代码示例吗?

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


【解决方案1】:

是的,您可以将其包装在活动记录事务中,以便在单个事务中执行所有创建。有点像:

begin
  ActiveRecord::Base.transaction do
    10.times do
      p = current_user.people.create!(:first_name   => Faker::Name.first_name,
                                :last_name    => Faker::Name.last_name,
                                :email        => Faker::Internet.email)
      p.sample = true
      p.save
    end
  end
  rescue => e
    // throw your error and rollback
  end

【讨论】:

  • 这仍然会执行相同数量的查询。事务应该使 INSERT 更快,因为当事务提交时,所有插入都可以由数据库持久化,但不会减少您与数据库交谈的次数(实际上会增加两次)。
  • @muistooshort:正确。我自己才发现的。
猜你喜欢
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
  • 2017-05-19
  • 2017-01-02
  • 1970-01-01
  • 2018-11-22
  • 2011-07-18
  • 1970-01-01
相关资源
最近更新 更多