web-dev-qa-db-ja.com

Rails 3でのバッチ挿入

私はRails App。

それを行う「レールの方法」は何でしょうか?高速で正しい方法。

属性の文字列連結によってSQLクエリを作成できることは知っていますが、より良いアプローチが必要です。

38
phoenixwizard

ActiveRecord .create メソッドは一括作成をサポートします。このメソッドは、DBが機能をサポートしていない場合は機能をエミュレートし、機能がサポートされている場合は基盤となるDBエンジンを使用します。

オプションの配列を渡すだけです。

# 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
58
Simone Carletti

@Simone Carlettiと@Sumit Munotの2つの回答の後に、ようやく解決に至りました。

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のソリューションはより意味があります:)

20
phoenixwizard

Railsモデルでスクリプトを作成し、そのスクリプトに挿入するクエリを記述します。Railsを使用してスクリプトを実行できます。

Rails runner MyModelName.my_method_name

私のプロジェクトで使用した最良の方法です。

更新:

私は私のプロジェクトで以下を使用していますが、SQLインジェクションには適切ではありません。このクエリでユーザー入力を使用していない場合、それはあなたのために働くかもしれません

user_string = " ('[email protected]','a'), ('[email protected]','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)
3
Sumit Munot

あなたはそれを高速な方法で行うことができます、またはRails way;)Postgresにバルクデータをインポートする私の経験で最良の方法はCSV経由です。 Railsの方法では数分かかりますが、PostgresのネイティブCSVインポート機能を使用すると数秒かかります。

http://www.postgresql.org/docs/9.2/static/sql-copy.html

さらに、データベーストリガーをトリガーし、データベースの制約を尊重します。

編集(コメントの後):了解。その場合、2つのオプションを正しく説明しました。私は以前と同じ状況にあり、Rails 1000 save!戦略を使用して実装しました。これは最も簡単なものだったためです。それは、パフォーマンスが桁違いに優れていたからです。

もちろん、時期尚早の最適化はすべての悪の根源なので、たぶんそれを単純な遅いRails方法で行います。あなたの本当の質問は「何千ものクエリを必要としないRailsyの方法はありますか?」-残念ながらその答えはノーです。

0
Chris Aitchison