ridgepoleで同一テーブルを定義

Railsなどのアプリケーションで、古いデータを保管するためのアーカイブテーブルを作りたい場合があります。

ridgepoleのスキーマ定義はrubyのDSLになっているため、以下のようにテーブル名の配列からデッドコピーのスキーマを定義できました。

["users", "a_users"].each do |tbl_name|
  create_table tbl_name do |t|
    t.string        "name"
    t.string        "email", :null => false
    t.timestamps
  end
  add_index tbl_name, ["name"]
end

これにより、オンラインテーブルのスキーマを変更する際にアーカイブテーブルが不整合になるトラブルを避けられます。

保証されていない使い方のような気もしますが、現状、PostgreSQLとの組み合わせでは、とくに問題なく動作しています。

アーカイブ処理の実装例

このスキーマ定義の例ではUserモデル(usersテーブル)に以下のようなメソッドを定義することで、AUser(a_usersテーブル)にデータを移動できます。

def archive!
  AUser.create! self.attributes
  self.delete
end

トランザクションは途中でエラーが起きるとロールバックするまでロックされるため避けています。