Movatterモバイル変換


[0]ホーム

URL:


rochefort's blog

この広告は、90日以上更新していないブログに表示しています。

PostgreSQLからsqliteの移行をRailsを使って行う

この記事は

Ruby on Railsのカレンダー | Advent Calendar 2021 - Qiita 18日目の記事です。
昨日に引き続き、空いていたので参加してみました。
 

背景

昨日、Advent Calender Ranking 2021New RelicをRailsアプリにinstallしたところ、DB部分で速度が出ていないことが分かりました。
 
当初、このRailsアプリはHerokuにデプロイし、postgres add-onn を利用していましたが、レコードの上限数を超えたため、とりあえず無料で使えるElephantSQLへ乗り換えていました。
(この辺の話は以下に記載)

herokuのRailsアプリでDBをElephantSQLにしてみた - rochefort's blog

 
こいつが若干遅いということは分かっていたのですが、今はHerokuからVPSに移行しているので、今回ElephantSQLからDBの移行を行いました。

以下、本題。

DBの選択

PostgreSQLMySQLサービスを使っても良いのですが、メモリ使うし、
まぁ、sqlite使って壊れても割と簡単にデータ復旧できるし問題ないだろうという判断でsqliteへの移行を行うことにしました。

ElephantSQLからのdump取得

これは簡単で、consoleからボタンひとつで取り出せます。

sqliteへの取り込み

ここが今回はまりました。

dumpはsql形式なので、ちょこっと編集すればsqliteに取り込むのも簡単だろうと思っていましたが、dumpはcopy句を使っていて、これが現在のsqliteでは使えません。

他にもPostgreSQLのdumpをsqliteに変換できるJava系のツールも公開されていたので試してみましたが、古いようで動きませんでした。

後は、csvに変換して取り込む方法ですが、NULLが空白になっちゃうし(アプリケーション的には問題ないけど、なんとなく嫌)、他の方法を思索したところ、Rails6のMultiple Databaseの機能を使って移行できるのではないかという考えが思いつきました。

ご参考)
Active Record で複数のデータベース利用 - Railsガイド

やってみる

事前準備として、ElephantSQLのdumpを移行元PostgreSQLとしてimportしておきます。
また、移行先のsqliteも必要ですので、一時的にdatabase.ymlを変更し新しいDBを作って、rails db:migrate しておきます。

multiple DB設定

config/database.yml に移行先(sqlite)、移行元(PostgreSQL)の定義をしておきます。

development:  # 移行先  primary:    database: db/production.sqlite3    adapter: sqlite3    pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>  # 移行元  primary_replica:    adapter: postgresql    encoding: unicode    database: postgres-rails-app    pool: 5    username: rochefort    password:

ApplicationRecordに primary、primary_replicaのデータベースロール(writing, reading)を設定するだけ。

classApplicationRecord <ActiveRecord::Baseself.abstract_class =true  connects_todatabase: {writing::primary,reading::primary_replica }end

移行

後はrails consoleで読み書きするだけです。
書き込みは、Rails6から利用できるinsert_all を活用。

defcopy_table(klass)  list =nilActiveRecord::Base.connected_to(role::reading)  { list = klass.all }ActiveRecord::Base.connected_to(role::writing)  { klass.insert_all(list.map(&:attributes)) }end# examplecopy_table(Author)

感想

という感じで、サクッとできました。
当初考えていたdumpのsqlを手動で変更する手間もないですし、csv経由でやるより簡単な印象です。
 
こんなことのためにMulti DB使ってるのは私ぐらいでしょうが、RailsのMulti DB自体は設定も簡単なので良いですね。

See Also

About
id:rochefortid:rochefort

Ruby・Rails・Mac・Web・Tech、時々日々のことについて書いています。

follow
Search
Top Entries
はてなブックマーク数
Categories
Comments

    引用をストックしました

    引用するにはまずログインしてください

    引用をストックできませんでした。再度お試しください

    限定公開記事のため引用できません。

    読者です読者をやめる読者になる読者になる

    [8]ページ先頭

    ©2009-2025 Movatter.jp