2019/07/11 追記
この挙動ですが、v1.0.0以降のversionでは修正されているようです。
記事作成時に利用していたversionは0.27.0でした。
@kikunantoka さん ご指摘ありがとうございました!
RailsでRDBのレコードを一括処理したいときにactiverecord-importを使っていたのですが、
うまくデータ更新されてないものが見つかったので調査した結果の覚書です。
(RDBMSがMySQLの場合の話です)
on_duplicate_key_update
bulk_insertする際、新規レコードは作成、そうでないものは更新してくれるオプション。
activerecord-importでも対応しています。
https://github.com/zdennis/activerecord-import/wiki/On-Duplicate-Key-Update
which allows you to specify fields whose values should be updated if a primary or unique key constraint is violated.
とあるように、主キー / ユニークキー制約に引っかかった場合、対象レコードの指定したカラムの値だけ更新してくれます。
Foo.import [foos], on_duplicate_key_update: [:col1, :col2]
間違っていた部分とその結果
作成 / 更新の両方があり得るテーブルに対して、on_duplicate_key_update
オプションを指定せずにimportしていました。
Foo.import [foos]
この場合、例外処理が起きるか、更新されずに放置されるかだと思っていたのですが、最終更新日時(updated_at)のカラムだけが更新されるようです。
INSERT INTO `foos` (`id`, `col1`, `col2`, ..., `created_at`, `updated_at`)
VALUES (...)
ON DUPLICATE KEY UPDATE `foos`.`updated_at` = VALUES(`updated_at`)
結果として、更新はされている(ように見える)がカラムの値は何も変わっていないレコードが生まれていました。
on_duplicate_key_update
オプションを指定したら正常に更新されるようになりました。一安心。