🧹

TypeORMのマイグレーションファイルをまとめる

2022/02/02に公開

TypeScript のデータベースORMライブラリである TypeORM のマイグレーションファイルが増えてきたので一旦1つにまとめてようとして行ったこと。

以下、試したときの TypeORM のバージョンは 0.2.34 です。今後のバージョンで動作が変わっているかもしれません。

マイグレーション動作を確かめる

TypeORM はデータベースに migrations テーブルを自動的に作成して、timestamp と name カラムを持つレコードがマイグレーション毎に保存されます。

マイグレーション処理は、migrations ディレクトリ内のファイルをファイル名の昇順に辿りますす。そのファイルが既に実行済みかどうかを、migrations テーブルにレコードがあるかで判断して、未処理であれば実行するようです。

当初の予想では、migrations テーブルの最もタイムスタンプが新しいレコードを取得して、それより新しいタイムスタンプで始まるマイグレーションファイルを実行していくと考えましたが違っていました。(予想通りだった場合には、最新のレコードだけ残して古いレコードは消してしまおうと考えていました。)

まとめた方法とリリース手順

今回は PostgreSQL で行いました。

定義の準備と確認

A. 現状の差分を全て適用したスキーマ定義を記録

  1. ローカルでデータベースを作成して最新のマイグレーションまで適用します。
  2. pg_dump コマンドに --schema-only オプションを指定して、スキーマをファイルにダンプします。

B. まとめた後のスキーマ定義を記録

  1. ローカルでデータベースを作成します。空の状態です。
  2. migrations ディレクトリの中のファイルを別の場所に退避します。
  3. ここでマイグレーション生成する(typeorm migration:generate)と、まとまったマイグレーション処理になります。(このマイグレーションファイルを控えておきます。)
  4. pg_dump コマンドに --schema-only オプションを指定して、スキーマをファイルにダンプします。

上記 A, B のスキーマダンプを diff して定義が変わっていないことを確かめます。(
自分が試した際は使わなくなっていたシーケンスが残っていたので差分がありました。)

リリース手順

まとめるポイントとマイグレーションを予め作っておいて、後でそこを差し替えて古いものは削除します。

C. まとめるポイントを作る

  1. ローカルでデータベースを作成して最新のマイグレーションまで適用します。
  2. まとめるポイント(ファイルとしてはこれだけ最後残す)となるマイグレーションを生成(generate)します。差分がないのでup,downメソッドは空です。
  3. このマイグレーションをリリースします。

D. マイグレーションをまとめる

  1. migrationsディレクトリの中のファイルを最新の C.2.で作ったファイル以外消します。
  2. 最新のファイルの中身の up, down メソッドを B.3. で作ったマイグレーション内容に置き換えます。
  3. このマイグレーションをリリースします。(デプロイ環境では何も処理されません。)

補足

古い migrations レコードを残している理由

古いアプリケーションが誤ってデプロイされてしまったときにマイグレーションが走るのを防ぐため。また記録として残すため。 typeorm migration:show も定義ファイルに対して適用状態をチェックするので、残っていて問題ないです。

差し替えるマイグレーションについて

前述のとおり、自分が行った際には不要なシーケンスが残っていたため、それらを DROP する処理を当初にいれておきました。また名前は最終的にここが出発点になるので、それを意識して命名すると良いでしょう。

Discussion