DBは普段GUIでしか扱わないのだけれども、バックアップとリストアについて調べておく。
参考URL: How To Use The SQLite Dump Command
インストール
sudo apt install sqlite3
データベースのdump
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
sqlite> .output db/dump.sql
sqlite> .dump
sqlite> .exit
特定のテーブルをdump
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
sqlite> .output db/videos.sql
sqlite> .dump videos
sqlite> .exit
これひょっとすると対話型のコマンドで実行しなくてもいけるのではという気持ちもある。
特定のテーブルをdb:seedでリストア
ここからが本題である。
先程のコマンドでdump.sqlあるいはvideos.sqlが取得できた前提で実行する。
まずはテーブル全体を初期化する:
rails db:drop db:create db:migrate
Dropped database 'db/development.sqlite3'
Dropped database 'db/test.sqlite3'
Created database 'db/development.sqlite3'
Created database 'db/test.sqlite3'
== 20231123063711 CreateVideos: migrating =====================================
-- create_table(:videos)
-> 0.0020s
== 20231123063711 CreateVideos: migrated (0.0027s) ============================
つづいてseeds.rbを次のように更新する:
videos_sql = File.read("db/videos.sql")
result = ActiveRecord::Base.connection.execute(videos_sql)
rails db:seedしてみたところ残念ながらDBはリストアできていなかった。
試しにINSERT INTO行のみを実行してみたところ、レコードは1件のみ作成されていた。つまり複数行は実行できないようだ。
先程のseeds.rbを修正する:
videos_sql = File.read("db/videos.sql")
videos_sql.each_line do |sql|
if sql.match?(/^INSERT INTO/)
ActiveRecord::Base.connection.execute(sql)
end
end
いい感じだ。 たまたま今回はリストア対象のテーブルが1つしかなかったのでこれで十分だ。
ただしこの方法だとテーブルとSQLのカラムが一致している必要があるため、dumpをmigrationする度に行うか、INSERT INTO table_nameをINSERT INTO table_name (column, ...)と書き換える必要がある。若干不格好ではあるが、subなどのメソッドを使うとよい。