SQLマイグレーションツール「mig」に、同名のテーブル、カラム、インデックスを作成しようとしたというエラーの場合はマイグレーションをスキップするというオプションを追加しました。

以前ブログでも紹介したこともある、PHP製のシンプルなSQLマイグレーションツール「mig」ですが、こちら社内のDBマイグレーションツールとして絶賛使用中で、実は地道にバグフィックスや機能追加を行っています。

arakaji.hatenablog.com

その中で、メンバーからの要望があり追加した機能について紹介します。

同名のテーブル、カラム、インデックスを作成しようとしたというエラーが出た場合マイグレーションをスキップするオプション「skip-duplicate-and-exists-errors」

migでマイグレーションSQLファイルを作成するとファイル名のプレフィックスとしてタイムスタンプが付与され、マイグレーションを実行するとそのSQLファイルのタイムスタンプがmigrationsテーブルに追加されます。 マイグレーションを実行するときには、このテーブルのレコードを見て実行していないSQLを判断し実行しています。

しかし、例えばどこかの環境のDBのSQLダンプを取得してそれを実行して作ったDBの場合、そのSQLダンプ内にmigrationsテーブルが含まれていなければすでにテーブルやカラム、インデックスが作成されているのにそれらを作成をするSQLを実行しようとしてエラーが発生します。

マイグレーション実行時に「skip-duplicate-and-exists-errors」というオプションをつけると、同名のテーブル、カラム、インデックスを作成しようとしたというエラーの場合は、このマイグレーションSQLは実行したものとみなしてmigrationsテーブルにレコードを追加してスキップするという機能を追加しました。

$ mig-cli migrate skip-duplicate-and-exists-errors

なぜ追加したのか?

うちの開発チームではmigの利用は開発環境に限定していて、本番環境へは手動でSQLを実行しています。

理由はソースコードの変更と違い、DBへの変更はパフォーマンスへの影響も大きく実行順番やタイミングの調整も行いたいため、あえて手動で実行しています。

つまり、本番DBにはmigで使うmigrationsテーブルがありません。

以前「Paykeの技術基盤チームの取り組み」という内容で発表をしたこともあるのですが、Paykeでは開発環境にもほぼ本番同等のデータを使うようにしているため定期的に本番に類似したデータのdumpファイルを取り込んでいます。

speakerdeck.com

そのたびにmigrationsテーブルと実際の各テーブルの構成が変わってしまい、migで不要なエラーが発生してマイグレーションが進まないという問題が発生しておりました。

この問題を解決するため、「skip-duplicate-and-exists-errors」というオプションを追加することにしました。

ソフトウェアは使うと磨かれる

migは小さなソフトウェアですが、ホントに自分たちのユースケースとして必要だから開発して、それを実際に利用し、そのフィードバックをもとに少しづつ改善しています。

実際に自分で使ってみるだけだと今回のような機能は思いつかなかったですが、実際チームで使うなかでフィードバックがあって開発することができました。

この機能以外にも、一つのSQLファイルに複数のSQL文が入っていても実行できるようにしたり、SQLファイルの最後に複数の改行が入っている実行に失敗してしまうというバグを修正したりと、地味だけど着実に改善しています。

やはりソフトウェアは開発してリリースするだけだとだめで、実際使われてフィードバックを得ないと磨かれていかないのだと実感しました。

migはおそらくうちの社内だけで使っているソフトウェアですが、いつか世界中の人に使われて自分の名刺代わりになるようなソフトウェアを作っていけるように今後もコツコツやっていきます。