TypeORMのマイグレーションファイルをまとめる
TypeScript のデータベースORMライブラリである TypeORM のマイグレーションファイルが増えてきたので一旦1つにまとめてようとして行ったこと。
以下、試したときの TypeORM のバージョンは 0.2.34 です。今後のバージョンで動作が変わっているかもしれません。
マイグレーション動作を確かめる
TypeORM はデータベースに migrations テーブルを自動的に作成して、timestamp と name カラムを持つレコードがマイグレーション毎に保存されます。
マイグレーション処理は、migrations ディレクトリ内のファイルをファイル名の昇順に辿りますす。そのファイルが既に実行済みかどうかを、migrations テーブルにレコードがあるかで判断して、未処理であれば実行するようです。
当初の予想では、migrations テーブルの最もタイムスタンプが新しいレコードを取得して、それより新しいタイムスタンプで始まるマイグレーションファイルを実行していくと考えましたが違っていました。(予想通りだった場合には、最新のレコードだけ残して古いレコードは消してしまおうと考えていました。)
まとめた方法とリリース手順
今回は PostgreSQL で行いました。
定義の準備と確認
A. 現状の差分を全て適用したスキーマ定義を記録
- ローカルでデータベースを作成して最新のマイグレーションまで適用します。
-
pg_dump
コマンドに--schema-only
オプションを指定して、スキーマをファイルにダンプします。
B. まとめた後のスキーマ定義を記録
- ローカルでデータベースを作成します。空の状態です。
- migrations ディレクトリの中のファイルを別の場所に退避します。
- ここでマイグレーション生成する(
typeorm migration:generate
)と、まとまったマイグレーション処理になります。(このマイグレーションファイルを控えておきます。) -
pg_dump
コマンドに--schema-only
オプションを指定して、スキーマをファイルにダンプします。
上記 A, B のスキーマダンプを diff
して定義が変わっていないことを確かめます。(
自分が試した際は使わなくなっていたシーケンスが残っていたので差分がありました。)
リリース手順
まとめるポイントとマイグレーションを予め作っておいて、後でそこを差し替えて古いものは削除します。
C. まとめるポイントを作る
- ローカルでデータベースを作成して最新のマイグレーションまで適用します。
- まとめるポイント(ファイルとしてはこれだけ最後残す)となるマイグレーションを生成(generate)します。差分がないのでup,downメソッドは空です。
- このマイグレーションをリリースします。
D. マイグレーションをまとめる
- migrationsディレクトリの中のファイルを最新の C.2.で作ったファイル以外消します。
- 最新のファイルの中身の up, down メソッドを B.3. で作ったマイグレーション内容に置き換えます。
- このマイグレーションをリリースします。(デプロイ環境では何も処理されません。)
補足
古い migrations レコードを残している理由
古いアプリケーションが誤ってデプロイされてしまったときにマイグレーションが走るのを防ぐため。また記録として残すため。 typeorm migration:show
も定義ファイルに対して適用状態をチェックするので、残っていて問題ないです。
差し替えるマイグレーションについて
前述のとおり、自分が行った際には不要なシーケンスが残っていたため、それらを DROP する処理を当初にいれておきました。また名前は最終的にここが出発点になるので、それを意識して命名すると良いでしょう。
Discussion