Albacore v2.xを使って、FluentMigratorを実行する

以前、RakeタスクからFluetnMigratorを実行しましたが、Albacore v2.xではfluentmigratorメソッドがなく、Wikiに書かれている内容では実行できませんでした。

そんな中、Albacore v2.xのGitHubを眺めていたところ、albacore/fluent_migrator.rbとそれに対応するspecのalbacore/fluent_migrator_spec.rbを見つけました。

Gitのログを見ていると、それらはv2.0.0のリリース後の2014/9/3に更新されていることが分かりました。

ということは、Wikiなどには記載されていないものの、もしかしたらAlbacore v2.xでもFluentMigratorを実行できるのではと考え、試してみました。

 

環境

 

Albacore v2.x のコードを読んでみる

ここでは現バージョンである、Albacore 2.3.8のコードを読んでみます。

 

Albacore::Tools::FluentMigrator::Cmdクラス
initializeメソッド

17行目にあるinitializeメソッドにて、FluentMigratorのコマンドやパラメータを生成しています。

21行目で、FluentMigrator用の設定を行っています。initializeメソッドの引数になかった内容については、ここでデフォルト値を設定しています。

71行目で、mono_commandメソッドを実行して、Monoでも動作するようにしています。

 

executeメソッド

74行目にありますが、ここでFluentMigratorを実行しているようです。

 

Albacore::Tools::FluentMigrator::MigrateCmdFactoryクラス

Albacore::Tools::FluentMigrator::Cmdクラスを直接生成しても良さそうでしたが、ファクトリメソッドを持つクラス(MigrateCmdFactory)が176行目にあったため、こちらも見てみます。

ファクトリメソッドなので、initializeではなく、MigrateCmdFactory.createというクラスメソッドを使ってインスタンスを生成します。

 
以上より、MigrateCmdFactory.createでインスタンスを生成した後、executeメソッドを使えば実行できそうに見えたので、試してみることにします。

 

事前準備

上記のgemやNuGetのパッケージをインストールします。

FluentMigratorについては、以前と同様、以下の2ファイルをリンクとして追加し、ビルド時に出力ディレクトリへとコピーするようにします。

  • FluentMigrator.Runner.dll
  • Migrate.exe

 

Rakefileの作成

今回は、FluentMigratorのRakeタスクの書き方に似たような感じで作成してみます。

 

MigrateCmdFactory.create の引数を確認

FluentMigratorの実行に関するものは、MigrateCmdFactory.createの引数として渡せます。主な引数は以下の通りです。

メソッドの引数名 対応するオプションなど
exe FluentMigratorの実行ファイル path/to/Migrate.exe
dll --target FluentMigraotorのマイグレーションファイルが含まれるexeやdll
db --db sqlitepostgresなど
conn --conn FluentMigratorで使う、接続文字列
direction --task migraterollbackなど
extras 他のオプション 単一は"--steps=2"複数は配列で["--steps=2", "--output=true"]
interactive 該当なし falseで対話画面なし

参考: Command Line Runner Options · schambers/fluentmigrator Wiki · GitHub

 
注意しなければいけないのはinteractiveです。FluentMigratorには存在しないオプションですが、デフォルトがtrueとなっているため、何も指定しないと対話式になってしまいます。

 

invoke_taskの修正

FluentMigratorのWikiでは、

Rake.application.invoke_task("db:migrator[\"migrate\"]")

となっていますが、このままコピペをして実行すると、

-conn "Data Source=D:\db\albacore.db" --timeout=200 --task "migrate"

のようにtaskがダブルクオーテーションで囲まれて指定されるため、マイグレーション自体が実行されなくなります。

そのため、

Rake.application.invoke_task("db:migrator[migrate]")

のようにダブルクオーテーションを外すと、実行結果が以下となり、問題なく実行されます。

-conn "Data Source=D:\db\albacore.db" --timeout=200 --task migrate

 

reenableinvoke_taskはそのまま

reenableinvoke_taskにも手を付けようかと考えましたが、以下を読んで今回はそのままにしておきます。

 

存在しないfluentmigratorメソッドを修正

fluentmigratortaskに直します。

 
以上で完了です。

 

実行

FluentMigratorが実行できました。

d:\GitHub\Albacore-FluentMigrator-sample>bundle exec rake db:migrate --trace
DL is deprecated, please use Fiddle
** Invoke db:migrate (first_time)
** Invoke db:migrate:up (first_time)
** Execute db:migrate:up
** Invoke db:migrator (first_time)
** Execute db:migrator
packages\FluentMigrator.Tools.1.3.1.0\tools\x86\40\Migrate.exe -a Albacore-FluentMigrator-sample\bin\Debug\Albacore-FluentMigrator-sample.exe -db sqlite -conn "Data Source=D:\db\albacore.db" --timeout=200 --task migrate --steps=2
-------------------------------------------------------------------------------
=============================== FluentMigrator ================================
-------------------------------------------------------------------------------
Source Code:
  http://github.com/schambers/fluentmigrator
Ask For Help:
  http://groups.google.com/group/fluentmigrator-google-group
-------------------------------------------------------------------------------
[+] Using Database sqlite and Connection String "Data Source=D:\db\albacore.db"
-------------------------------------------------------------------------------
VersionMigration migrating
-------------------------------------------------------------------------------
[+] CreateTable VersionInfo
[+] VersionMigration migrated
-------------------------------------------------------------------------------
VersionUniqueMigration migrating
-------------------------------------------------------------------------------
[+] CreateIndex VersionInfo (Version)
[+] AlterTable VersionInfo
[+] CreateColumn VersionInfo AppliedOn DateTime
[+] VersionUniqueMigration migrated
-------------------------------------------------------------------------------
VersionDescriptionMigration migrating
-------------------------------------------------------------------------------
[+] AlterTable VersionInfo
[+] CreateColumn VersionInfo Description String
[+] VersionDescriptionMigration migrated
-------------------------------------------------------------------------------
1: Mig_01_CreateTable migrating
-------------------------------------------------------------------------------
[+] CreateTable user_table
[+] 1: Mig_01_CreateTable migrated
-------------------------------------------------------------------------------
2: Mig_02_InsertData migrating
-------------------------------------------------------------------------------
[+] -> 1 Insert operations completed in 00:00:00.0050003 taking an average of 00:00:00.0050003
[+] 2: Mig_02_InsertData migrated
[+] Task completed.
** Execute db:migrate

 
アンドキュメントな内容ですが、自分でいろいろと実装するのが手間なので、コードが残っている限りは使えそうです。

 

ソースコード

GitHubに上げておきました。
thinkAmi-sandbox/Albacore-FluentMigrator-sample