2016-09-05 22 views
0

をインポートしています。私はCSVファイルから55,000以上のレコードをデータベースにインポートします。これは私が使用しているコードです:gem 'postgres-copy'を使用してCSVファイル

CSV.foreach(Rails.root.join('db/seeds/locations.csv'), headers: true) do |row| 
    val    = Location.find_or_initialize_by(code: row[0]) 
    val.name   = row[1] 
    val.ecc   = row[2] || 'MISSING' 
    val.created_by  = User.find_by(name: 'anh') 
    val.updated_by  = User.find_by(name: 'anh') 
    val.save! 
end 

しかし、それは遅すぎます。私は公式のドキュメントを読んで、私は、クラスメソッドcopy_fromを使用して仕事をすることができると信じていますが、私の現在のコードを読んでいると、データを別のテーブル(関連)に参照しています。関連性やバリデーションについて何も言及していない。したがって、私はそれを解決する方法があるかどうか疑問に思っています。私はこの宝石を使うのは初めてです。読んでくれてありがとう。

答えて

0

私はその宝石は分かりませんが、PostgreSQLのCOPYが1つのテーブルで動作するので、マルチテーブルコピーをサポートできれば非常に驚いています。 50K行はそれほど多くはありません。トランザクションごとに1つのコミットを避けるために、トランザクション内で挿入をラップすることもできます。これは一度にあなたの行500件のレコードを挿入し、あなたが顕著なスピードアップが表示されるはずです

User.connection.begin_transaction 
i = 0 
CSV.foreach(...) do |row| 
    ... # your original code here 

    i += 1 
    if i % 500 == 0 
    User.connection.commit_transaction 
    User.connection.begin_transaction 
    end 
end 
User.connection.commit_transaction 

:あなたががトランザクション内のすべての50Kをラップしたい疑問が、このような何か。スイートスポットを見つけるために500という値で遊んでください。

+0

お寄せいただきありがとうございます。それは有り難いです。私はそれをテストし、その結果をあなたに知らせるつもりです。良い一日を。 :) –

0

これで、複数のテーブルをコピーできないため、POSTGRESQLのCOPYコマンドを利用できないことを理解しました。したがって、私はgem activerecord-importに切り替えます。前述のPhilip Hallstromの方法と比較すると、activerecord-importを使用すると、1m20sと1m54sの間で8000を超えるレコードが高速に読み込まれます。 これはgem activerecord-importをインストールした後の私のコードです。うまくいけば、それは他の人を助けることができる。

locations = [] 
columns = [:code, :name, :ecc] 
CSV.foreach(Rails.root.join('db/seeds/locations.csv'), headers: true) do |row| 
    val    = Location.find_or_initialize_by(code: row[0]) 
    val.name   = row[1] 
    val.ecc   = row[2] || 'MISSING' 
    val.created_by  = User.find_by(name: 'anh') 
    val.updated_by  = User.find_by(name: 'anh') 
    locations << val 
end 
Location.import columns, locations, validate: false 
関連する問題