Quantcast
Channel: Ruby on Railsの記事一覧|TechRacho by BPS株式会社
Viewing all articles
Browse latest Browse all 1406

SQLite on Railsシリーズ(07)ローカルスナップショット(翻訳)

$
0
0

概要

原著者の許諾を得て翻訳・公開いたします。

参考: Rails 8はSQLiteで大幅に強化された「個人が扱えるフレームワーク」(翻訳)|YassLab 株式会社

日本語タイトルは内容に即したものにしました。

SQLite on Railsシリーズ(07)ローカルスナップショット(翻訳)

今回は、SQLiteによってRuby on Railsアプリケーションのデータベース操作をどのように強化できるかについて考えます。SQLiteのデータベースは単なるファイルなので、スナップショットやクローンもシンプルかつ強力です。


Web アプリケーションで作業していると、ある時点でデータベースに関連するさまざまなタスクが発生します。

  • データベースのスナップショットを作成する必要が生じる。
  • データベースを以前に保存したスナップショットに復元する必要が生じる。
  • productionデータベースをローカルに複製する必要が生じる。
  • productionのデータを既存のローカルデータベースにマージする必要が生じる。
  • 別のブランチ固有のデータベースのデータを現在のブランチのデータベースにマージする必要が生じる。

もうおわかりでしょう。別プロセスで実行されるデータベースエンジン(別のコンピュータ上にあることが多い)を使っていると、これらのタスクは、不可能ではないにしても多少面倒になる可能性があります。

確かにPostgreSQLにはpg_dumppg_restoreというツールがありますが、以下の実行例を見ればわかるように、使い方は簡単ではありません1

pg_dump -U postgres -h localhost -p 5432 -F c -b -v -f /dev/null DB_NAME 2>&1

私の意見では、SQLiteならこうした操作は非常に簡単です。それでは1つずつ確認してみましょう。

原注

すべてのコードはRake名前空間内に配置されます。理由は、最終的にRailsアプリケーションの/lib/tasksディレクトリに配置するタスクファイルを準備し、アプリ内で日常的にこれらのタスクを素早く手軽に実行できるようにするためです。

🔗 データベースのスナップショットを作成する

データベースのスナップショットは、特定時点のデータのコピーです。データベース全体がファイルシステム上の単なるファイルであれば、スナップショットの取得は以下のように簡単です。

namespace :snap do
  task :create do
    @snapshot_dir = Rails.root.join('storage/snapshots')
    @db_path = ActiveRecord::Base.connection_db_config.database
    @db_name = @db_path.rpartition('/').last.remove('.sqlite3')

    timestamp = DateTime.now.to_formatted_s(:number)
    snap_name = "#{@db_name}-#{timestamp}.backup"
    snap_path = Pathname(@snapshot_dir).join(snap_name)

    FileUtils.copy_file(@db_path, snap_path)
  end

上のコードには定型文がいくつかありますが、核となるのはデータベースファイルをコピーするための単なるcp呼び出しです。現在のActive Recordデータベース パスを取得し、タイムスタンプ付きのスナップショットファイル名を用意して、データベースファイルをコピーするだけです。

スナップショットは、スキーマとデータを含む保存ポイントを作成して、後で簡単に戻せるのが便利です。

🔗 スナップショットをリストアする

スナップショットを取得したら、いずれデータベースをその時点に復元する必要がある場合が生じるでしょう。通常、データベースのスキーマやデータ(あるいはその両方)を変更する実験を開始する前にスナップショットを取得しておきます。必要に応じて変更を元に戻せるようにしたいので、最初にスナップショットを取得し、後で元に戻します。

単純なSQLiteファイルでスナップショットの復元がどのように行われるかは想像がつくでしょう。

namespace :snap do
  task :restore do
    @snapshot_dir = Rails.root.join('storage/snapshots')
    @db_path = ActiveRecord::Base.connection_db_config.database
    @db_name = @db_path.rpartition('/').last.remove('.sqlite3')
    @snaps = Pathname(@snapshot_dir)
      .children
      .select do |path|
        path.extname == ".backup" &&
        path.basename.to_s.include?(@db_name)
      end
      .sort
      .reverse

    latest_snapshot = @snaps.first

    FileUtils.remove_file(@db_path)
    FileUtils.copy_file(latest_snapshot, @db_path)
  end
end

スナップショットの復元自体は簡単です。

  • 現在のデータベースの最新のスナップショットを取得します。
  • 次に、現在のデータベースファイルを削除し、スナップショット ファイルを現在のデータベース ファイルの場所にコピーします。

ここでも、単純なファイルを操作しているため、基本的にはcpによるコピーコマンドの周りに適切な定型文を配置すればおしまいです。


SQLiteのデータベースはファイルシステム上の単なるファイルに過ぎないので、production環境データの操作もシンプルになります(これについては今後の記事で取り上げます。現時点では、ローカルデータベースのスナップショットを作成して復元する方法は記事1本で十分でしょう)。

少し整理して仕上げれば、以下のように利用できる/lib/tasks/dbsnap.rakeファイルを作成できます。

bin/rails db:snap:list
bin/rails db:snap:create
bin/rails db:snap:restore

これで、productionデータベースを操作する機能も追加する基盤が確立されます。

今回の完全なコードはこのGistでご覧いただけます。

関連記事

SQLite on Railsシリーズ(01)Gitブランチごとにデータベースを切り替える(翻訳)

SQLite on Railsシリーズ(02)SQLiteをチューニングで強化する(翻訳)

SQLite on Railsシリーズ(03)SQLite拡張機能を読み込む(翻訳)

SQLite on Railsシリーズ(04)LitestreamでSQLiteをバックアップしよう(翻訳)


  1. 原注: このコマンドは、PostgreSQLスナップショットを操作するためのよりシンプルなCLIユーティリティを提供するpg-snapリポジトリから取得できます。 

The post SQLite on Railsシリーズ(07)ローカルスナップショット(翻訳) first appeared on TechRacho.


Viewing all articles
Browse latest Browse all 1406

Latest Images

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

Trending Articles



Latest Images

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭

赤坂中華 わんたん亭