まとめると
- ec2上で
activerecord-importのbulk upsertを使いたい - 使うデータベースは
sqlite3 - ただ、ec2上で簡単にインストールできる
sqlite3のバージョンは、bulk upsertに対応していない - 頑張って新しいバージョンの
sqlite3をダウンロードし、なんとしてもbulk upsertする。
背景
Rubyで大量のデータを扱いたい、railsじゃないけどactiverecordの恩恵を受けたい、というそこのアタナ、こんなgemがあります。
activerecord-import is a library for bulk inserting data using ActiveRecord.
素晴らしい。
もちろんbulk insertもしたいのですが、すこし欲張って、bulk upsertもしたい。そんなときがありました。
MySQL, PostgreSQL (9.5+), and SQLite (3.24.0+) support on duplicate key update (also known as "upsert") which allows you to specify fields whose values should be updated if a primary or unique key constraint is violated.
One big difference between MySQL and PostgreSQL support is that MySQL will handle any conflict that happens, but PostgreSQL requires that you specify which columns the conflict would occur over. SQLite models its upsert support after PostgreSQL.
This will use MySQL's ON DUPLICATE KEY UPDATE or Postgres/SQLite ON CONFLICT DO UPDATE to do upsert.
ここで注目すべきは、バージョンの部分。
SQLite (3.24.0+)
このバージョンを満たしていないと、以下のようなエラーが出ます
/Users/matt/.chefdk/gem/ruby/2.4.0/gems/activerecord-import-0.22.0/lib/activerecord-import/adapters/abstract_adapter.rb:50:in `post_sql_statements': private method `warn' called for nil:NilClass (NoMethodError)
from /Users/matt/.chefdk/gem/ruby/2.4.0/gems/activerecord-import-0.22.0/lib/activerecord-import/import.rb:709:in `import_without_validations_or_callbacks'
from /Users/matt/.chefdk/gem/ruby/2.4.0/gems/activerecord-import-0.22.0/lib/activerecord-import/import.rb:662:in `import_with_validations'
from /Users/matt/.chefdk/gem/ruby/2.4.0/gems/activerecord-import-0.22.0/lib/activerecord-import/import.rb:602:in `import_helper'
from /Users/matt/.chefdk/gem/ruby/2.4.0/gems/activerecord-import-0.22.0/lib/activerecord-import/import.rb:458:in `import'
from load_person_data.rb:194:in `block in <main>'
Macユーザーだと、brew経由でこのバージョンをインストールできるのですが、EC2上だとそうも行きませんでした。
ほしいバージョンのsqlite3をインストールする
ここからが本題です。
OSはubuntuを使っています。
手順は以下。
- パッケージのダウンロード
- パッケージの展開
- パッケージのビルド
- パッケージのインストール
1. パッケージのダウンロード
sqlite3 のパッケージのページを訪れ、以下のダウンロードリンクを確認
- sqlite3_3.24.0-1.dsc
- sqlite3_3.24.0.orig-www.tar.xz
- sqlite3_3.24.0.orig.tar.xz
- sqlite3_3.24.0-1.debian.tar.xz
それぞれ wgetでダウンロードしてくる
wget http://archive.ubuntu.com/ubuntu/pool/main/s/sqlite3/sqlite3_3.24.0-1.dsc
wget http://archive.ubuntu.com/ubuntu/pool/main/s/sqlite3/sqlite3_3.24.0.orig-www.tar.xz
wget http://archive.ubuntu.com/ubuntu/pool/main/s/sqlite3/sqlite3_3.24.0.orig.tar.xz
wget http://archive.ubuntu.com/ubuntu/pool/main/s/sqlite3/sqlite3_3.24.0-1.debian.tar.xz
2. パッケージの展開
dpkg-source -x sqlite3_3.24.0-1.dsc
3. パッケージのビルド
# 前項で展開されたディレクトリに移動
cd sqlite3-3.24.0/
sudo dpkg-buildpackage -d -uc -us
4. パッケージのインストール
# 依存関係があるので、この順番で。
sudo dpkg -i libsqlite3-0_3.24.0-1_amd64.deb
sudo dpkg -i libsqlite3-dev_3.24.0-1_amd64.deb
sudo dpkg -i sqlite3_3.24.0-1_amd64.deb
これで sqlite3 でも、 bulk upsert 使えます、ヤッタネ。
さいごに
ubuntu初心者なので、もっと簡単にインストールするやり方があればご教示ください。。。