我想从我的 Rails 应用程序中将几千条记录批量插入数据库(在我的情况下为 POSTGRES)。
这样做的“Rails 方式”是什么?一些快速且正确的方法。
我知道我可以通过属性的字符串连接来创建 SQL 查询,但我想要一个更好的方法。
我想从我的 Rails 应用程序中将几千条记录批量插入数据库(在我的情况下为 POSTGRES)。
这样做的“Rails 方式”是什么?一些快速且正确的方法。
我知道我可以通过属性的字符串连接来创建 SQL 查询,但我想要一个更好的方法。
ActiveRecord.create
方法支持批量创建。如果数据库不支持该功能,则该方法模拟该功能,如果支持该功能,则使用底层数据库引擎。
只需传递一系列选项。
# Create an Array of new objects
User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])
支持块,这是共享属性的常用方式。
# Creating an Array of new objects using a block, where the block is executed for each object:
User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
u.is_admin = false
end
在@Simone Carletti 和@Sumit Munot 的两个回答之后,我终于找到了解决方案。
在 postgres 驱动程序支持 ActiveRecord .create 方法的批量插入之前,我想使用activerecord-import gem。它在单个插入语句中进行批量插入。
books = []
10.times do |i|
books << Book.new(:name => "book #{i}")
end
Book.import books
在 POSTGRES 中,它导致单个插入语句。
一旦 postgres 驱动程序在单个插入语句中支持 ActiveRecord .create 方法的批量插入,那么@Simone Carletti 的解决方案就更有意义了:)
您可以在 Rails 模型中创建一个脚本,编写查询以插入该脚本在 Rails 中,您可以使用运行脚本
rails runner MyModelName.my_method_name
是我在项目中使用的最佳方式。
更新:
我在我的项目中使用以下,但它不适合 sql 注入。如果您没有在此查询中使用用户输入,它可能对您有用
user_string = " ('a@ao.in','a'), ('b@ao.in','b')"
User.connection.insert("INSERT INTO users (email, name) VALUES"+user_string)
对于多条记录:
new_records = [
{:column => 'value', :column2 => 'value'},
{:column => 'value', :column2 => 'value'}
]
MyModel.create(new_records)
您可以使用快速方式或 Rails 方式;)根据我的经验,将批量数据导入 Postgres 的最佳方式是通过 CSV。使用 Postgres 的本机 CSV 导入功能,Rails 方式将需要几分钟时间。
http://www.postgresql.org/docs/9.2/static/sql-copy.html
它甚至触发数据库触发器并遵守数据库约束。
编辑(在您发表评论后):明白了。在这种情况下,您已经正确描述了您的两个选项。我以前也遇到过同样的情况,使用 Rails 1000 save 实现它!策略,因为它是最简单的方法,然后将其优化为“附加一个巨大的查询字符串”策略,因为它的性能要好一个数量级。
当然,过早的优化是万恶之源,所以也许可以使用简单的慢速 Rails 方式,并且知道构建一个大查询字符串是一种完全合法的优化技术,但会牺牲可维护性。我觉得你真正的问题是'是否有一种不涉及 1000 个查询的 Railsy 方式?- 不幸的是,答案是否定的。