Posted at

[ActiveRecord]activerecord-import-0.15系で気をつけること

More than 3 years have passed since last update.

最近DBのBulk Insert用に、activerecord-importを使用してるのですが、Rails5対応で最新版のactiverecord-importにupdateし使用したところ、思いがけないところでハマってしまったので、備忘録として残しておきます


ハマってた内容


  • Insert用に用意したActiveRecordのModelインスタンス数とimport後のレコード数に差分が生じていた


原因


  • 0.15系だとvalidationがデフォルトでtrueの状態になっており、validationで引っかかっていることに気づかなかった

https://github.com/zdennis/activerecord-import/blob/master/lib/activerecord-import/import.rb#L344


対策

optionにfalseを渡すのも考えたが、validation通ってないデータが保存されるべきデータではないので、エラーメッセージ等、補足できないかなと調べた

どうやらreturn instanceに以下のものがあるっぽい


  • failed_instances : validationに失敗したり、commit失敗したinstanceを配列にして返す

  • num_inserts : 発行したInsert文の数

  • ids : adpaterがサポートされていればimportしたprimary keyのリストを返す

結論として下記のようにエラーが有無を判定することにしました

result = model_module.import instance_arr

if !result.failed_instances.blank?
logger.warn(result.failed_instances)
end

余談だが、MySQLの場合、下記のことも頭の片隅においておくと、原因解明に役立つかもしれないです(よほど大量のBulk Insertを発行しない限りは起きないとは思いますが...)


  • 1ステートメントあたりのパケットサイズのチェックを行っている

https://github.com/zdennis/activerecord-import/blob/master/lib/activerecord-import/adapters/mysql_adapter.rb#L34


  • パケットサイズの設定値の確認

SHOW VARIABLES like 'max_allowed_packet';


  • パケットサイズについて

https://dev.mysql.com/doc/refman/5.6/ja/packet-too-large.html