手軽に開発環境でデータベースのバックアップとリストアしたいので、やり方を調べてrakeタスク化する

SQLite3 のインストール

sqlite のコンソールを起動しようとしたら、sqlite が入っていなかったのでインストールする

$ rails db
Couldn't find database client: sqlite3. Check your $PATH and try again.

$ sudo apt install -y sqlite3
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Suggested packages:
  sqlite3-doc
The following NEW packages will be installed:
  sqlite3
0 upgraded, 1 newly installed, 0 to remove and 13 not upgraded.
Need to get 353 kB of archives.
After this operation, 546 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian bookworm/main amd64 sqlite3 amd64 3.40.1-2 [353 kB]
Fetched 353 kB in 0s (13.5 MB/s)
Selecting previously unselected package sqlite3.
(Reading database ... 67120 files and directories currently installed.)
Preparing to unpack .../sqlite3_3.40.1-2_amd64.deb ...
Unpacking sqlite3 (3.40.1-2) ...
Setting up sqlite3 (3.40.1-2) ...
Processing triggers for man-db (2.11.2-2) ...

$ rails db
SQLite version 3.40.1 2022-12-28 14:03:47
Enter ".help" for usage hints.
sqlite>

バックアップとリストア方法を確認

.help で使い方を確認して動作確認

sqlite> .help

.backup ?DB? FILE        Backup DB (default "main") to FILE
.restore ?DB? FILE       Restore content of DB (default "main") from FILE
$ rails db
SQLite version 3.40.1 2022-12-28 14:03:47
Enter ".help" for usage hints.
sqlite> .backup db/development.backup
sqlite> .restore db/development.backup

rails db だとコンソールを起動しないといけない。 sqlite3 コマンドで実行すると以下となる。

# バックアップ
$ sqlite3 db/development.sqlite3 ".backup db/development.sqlite3.backup"
# リストア
$ sqlite3 db/development.sqlite3 ".restore db/development.sqlite3.backup"

rake タスク

lib/tasks/db.rake を作成した。 データベースは database.yml を参照するようにして、RAILS_ENV 毎に切り替えられるようにした。

namespace :db do
  task backup: :environment  do
    command = "sqlite3 #{database} '.backup #{backup_file_name(database)}'"
    exec command
  end

  task restore: :environment do
    command = "sqlite3 #{database} '.restore #{backup_file_name(database)}'"
    exec command
  end

  def database
    db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
    db_configs.first.configuration_hash[:database]
  end

  def backup_file_name(database)
    "#{database}.backup"
  end
end

動作確認

# development
$ rails db:backup # バックアップ
$ ls db/development.sqlite3.backup
db/development.sqlite3.backup
$ rails db:restore # リストア

# production
$ RAILS_ENV=production rails db:backup # バックアップ
$ ls db/production.sqlite3.backup
db/production.sqlite3.backup
$ RAILS_ENV=production rails db:restore # リストア