昔のMS Accessテーブルを引っ張り出してくると、「なぜこのテーブルやカラムがあるのか?」を思い出せない時がありました。
そのため、MS Accessであってもテーブルスキーマのバージョン管理をしたくなりました。
そこで、Rubyで見たMigrationのようなものがC#にないかを探してみたところ、FluentMigrator
がありました。
schambers/fluentmigrator · GitHub
ドキュメントを見ると、Jetの文字がありました。MS Access (*.accdb)でも使えるかもしれないと考え、試してみることにしました。
Fluent Interface · schambers/fluentmigrator Wiki · GitHub
環境
- Windows7
- .NET Framework 4.5
- FluentMigrator 1.3.0.0
- MS Access (*.accdb)
準備
プロジェクトの作成
今回はコンソールアプリケーションプロジェクトを作成しました。(今回は、D:\GitHub\FluentMigrator-sample)
FluentMigratorのインストール
FluentMigratorはNuGetでインストールできます。
MS Accessテーブルの用意
空っぽの *.accdbファイル(今回は D:\GitHub\FluentMigrator-sample\sample.accdb)を用意します。
MS Accessのテーブルスキーマを作成・変更
公式のGetting Startedを参考に、MS Accessを使う上で気になるところを試してみました。
Home · schambers/fluentmigrator Wiki · GitHub
マイグレーションごとの内容は、以下の通りです。
No | ファイル名 | 内容 |
---|---|---|
1 | Migration2014110601.cs | Users テーブルにID (数値型、主キー)とName (テキスト型)を用意 |
2 | Migration2014110602.cs | Users テーブルのID をオートナンバー型に変更 |
3 | Migration2014110603.cs | Users テーブルにDescription (メモ型)を追加 |
Users
テーブルにID
(数値型)とName
(テキスト型)を用意
今回はマイグレーションファイルをまとめることにして、プロジェクトにMigrations
フォルダを作成します。
そして、その中にマイグレーションファイル(Migration2014110601.cs
)を作成します。
なお、マイグレーションファイルで使えるメソッドなどは、以下にまとまっていました。
Fluent Interface · schambers/fluentmigrator Wiki · GitHub
using FluentMigrator; namespace FluentMigrator_sample.Migrations { [Migration(2014110601)] public class Migration2014110601 : Migration { public override void Up() { Create.Table("Users") .WithColumn("ID").AsInt32().PrimaryKey() .WithColumn("Name").AsString(); } public override void Down() { Delete.Table("Users"); } } }
マイグレーションの実行
Migration Runnerとして、
が用意されていますが、今回は一番手軽なCommand Line Runnerを使ってみることにしました。
Migration Runners · schambers/fluentmigrator Wiki · GitHub
コマンドプロンプトを起動し、以下を実行します。
"D:\GitHub\FluentMigrator-sample\packages\FluentMigrator.1.3.0.0\tools\Migrate.exe" /conn "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\GitHub\FluentMigrator-sample\sample.accdb" /provider jet /assembly "D:\GitHub\FluentMigrator-sample\FluentMigrator-sample\bin\Debug\FluentMigrator-sample.exe" /verbose true
なお、Migrate.exe
やMS Access、今回作成したコンソールアプリケーションのパスは、環境に応じて変更します。
ログを見ると、Users
テーブルの他に、マイグレーション情報を格納するVersionInfo
テーブルも作成されたようです。
------------------------------------------------------------------------------- =============================== FluentMigrator ================================ ------------------------------------------------------------------------------- Source Code: http://github.com/schambers/fluentmigrator Ask For Help: http://groups.google.com/group/fluentmigrator-google-group ------------------------------------------------------------------------------- [+] Using Database jet and Connection String Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\GitHub\FluentMigrator-sample\sample.accdb ------------------------------------------------------------------------------- VersionMigration migrating ------------------------------------------------------------------------------- [+] Beginning Transaction [+] CreateTable VersionInfo CREATE TABLE [VersionInfo] ([Version] DECIMAL(20,0) NOT NULL) => 0.018001s [+] Committing Transaction [+] VersionMigration migrated => 0.0210012s ------------------------------------------------------------------------------- VersionUniqueMigration migrating ------------------------------------------------------------------------------- [+] Beginning Transaction [+] CreateIndex VersionInfo (Version) CREATE UNIQUE INDEX [UC_Version] ON [VersionInfo] ([Version] ASC) => 0.0030002s [+] AlterTable VersionInfo No SQL statement executed. => 0.001s [+] CreateColumn VersionInfo AppliedOn DateTime ALTER TABLE [VersionInfo] ADD COLUMN [AppliedOn] DATETIME => 0.0020002s [+] Committing Transaction [+] VersionUniqueMigration migrated => 0.0040003s ------------------------------------------------------------------------------- VersionDescriptionMigration migrating ------------------------------------------------------------------------------- [+] Beginning Transaction [+] AlterTable VersionInfo No SQL statement executed. => 0.0010001s [+] CreateColumn VersionInfo Description String ALTER TABLE [VersionInfo] ADD COLUMN [Description] TEXT => 0.0020002s [+] Committing Transaction [+] VersionDescriptionMigration migrated => 0.0040003s ------------------------------------------------------------------------------- 2014110601: Migration2014110601 migrating ------------------------------------------------------------------------------- [+] Beginning Transaction [+] CreateTable Users CREATE TABLE [Users] ([ID] INTEGER NOT NULL, [Name] VARCHAR(255) NOT NULL, CONST RAINT [PK_Users] PRIMARY KEY ([ID])) => 0.0040002s INSERT INTO [VersionInfo] ([Version], [AppliedOn], [Description]) VALUES (201411 0601, '2014-11-05 20:55:16', 'Migration2014110601') [+] Committing Transaction [+] 2014110601: Migration2014110601 migrated => 0.0510029s [+] Task completed.
MS Accessのテーブルを見ると、マイグレーションファイルの内容となっています。
このことより、MS Access (*.accdb)であっても、Jet
プロバイダを使えばマイグレーションができることが分かりました。
Users
テーブルのID
をオートナンバー型に変更
マイグレーションファイルMigration2014110602.cs
を作成します。
MS Accessのオートナンバー型にするには、Identity()
メソッドを使えばよいようです。
using FluentMigrator; namespace FluentMigrator_sample.Migrations { [Migration(2014110602)] public class Migration2014110602 : Migration { public override void Up() { Alter.Table("Users") .AlterColumn("ID").AsInt32().PrimaryKey().Identity(); } public override void Down() { Alter.Table("Users") .AlterColumn("ID").AsInt32().PrimaryKey(); } } }
マイグレーションの実行
No.1と同じコマンドを実行します。ログは以下の通りです。
------------------------------------------------------------------------------- =============================== FluentMigrator ================================ ------------------------------------------------------------------------------- Source Code: http://github.com/schambers/fluentmigrator Ask For Help: http://groups.google.com/group/fluentmigrator-google-group ------------------------------------------------------------------------------- [+] Using Database jet and Connection String Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\GitHub\FluentMigrator-sample\sample.accdb ------------------------------------------------------------------------------- 2014110602: Migration2014110602 migrating ------------------------------------------------------------------------------- [+] Beginning Transaction [+] AlterTable Users No SQL statement executed. => 0.001s [+] AlterColumn Users ID Int32 ALTER TABLE [Users] ALTER COLUMN [ID] COUNTER NOT NULL => 0.0130008s INSERT INTO [VersionInfo] ([Version], [AppliedOn], [Description]) VALUES (201411 0602, '2014-11-05 20:59:22', 'Migration2014110602') [+] Committing Transaction [+] 2014110602: Migration2014110602 migrated => 0.0290017s [+] Task completed.
実際のテーブルのID
列もオートナンバー型になっています。
Users
テーブルにDescription
(メモ型)を追加
さらに、マイグレーションファイルMigration2014110603.cs
を作成して、メモ型の列を追加してみます。
MS Accessではテキスト型のフィールドサイズが255までなので、それより長いサイズをAsString()
メソッドに渡すと、メモ型になるようです。
using FluentMigrator; namespace FluentMigrator_sample.Migrations { [Migration(2014110603)] public class Migration2014110603 : Migration { public override void Up() { Alter.Table("Users") .AddColumn("Description").AsString(256); } public override void Down() { Delete.Column("Description").FromTable("Users"); } } }
マイグレーションの実行
No.1と同じコマンドを実行し、ログを確認します。
------------------------------------------------------------------------------- =============================== FluentMigrator ================================ ------------------------------------------------------------------------------- Source Code: http://github.com/schambers/fluentmigrator Ask For Help: http://groups.google.com/group/fluentmigrator-google-group ------------------------------------------------------------------------------- [+] Using Database jet and Connection String Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\GitHub\FluentMigrator-sample\sample.accdb ------------------------------------------------------------------------------- 2014110603: Migration2014110603 migrating ------------------------------------------------------------------------------- [+] Beginning Transaction [+] AlterTable Users No SQL statement executed. => 0.0020001s [+] CreateColumn Users Description String ALTER TABLE [Users] ADD COLUMN [Description] TEXT NOT NULL => 0.0100005s INSERT INTO [VersionInfo] ([Version], [AppliedOn], [Description]) VALUES (201411 0603, '2014-11-05 21:03:21', 'Migration2014110603') [+] Committing Transaction [+] 2014110603: Migration2014110603 migrated => 0.0290016s [+] Task completed.
実際のテーブルにもDescription
列が追加されています。
ここで、VersionInfo
テーブルを見てみると、以下の通り3行が存在します。
マイグレーションのロールバック
試しにロールバックしてみます。
コマンドの最後に /task rollback
オプションを追加して実行します。
"D:\GitHub\FluentMigrator-sample\packages\FluentMigrator.1.3.0.0\tools\Migrate.exe" /conn "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\GitHub\FluentMigrator-sample\sample.accdb" /provider jet /assembly "D:\GitHub\FluentMigrator-sample\FluentMigrator-sample\bin\Debug\FluentMigrator-sample.exe" /verbose true /task rollback
ログを見ると、No.3からNo.2の状態に戻っています。画像は省略しますが、実際のテーブルも同様でした。
------------------------------------------------------------------------------- =============================== FluentMigrator ================================ ------------------------------------------------------------------------------- Source Code: http://github.com/schambers/fluentmigrator Ask For Help: http://groups.google.com/group/fluentmigrator-google-group ------------------------------------------------------------------------------- [+] Using Database jet and Connection String Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\GitHub\FluentMigrator-sample\sample.accdb ------------------------------------------------------------------------------- 2014110603: Migration2014110603 reverting ------------------------------------------------------------------------------- [+] Beginning Transaction [+] DeleteColumn Users Description ALTER TABLE [Users] DROP COLUMN [Description] => 0.0060003s DELETE FROM [VersionInfo] WHERE [Version] = 2014110603 [+] Committing Transaction [+] 2014110603: Migration2014110603 reverted => 0.0230013s [+] Task completed.
また、VersionInfo
テーブルを見ると、No.3の行が削除されています。
以上のようにFluentMigratorを使ってみましたが、なかなかよさそうでした。
あとはこれらのマイグレーションファイルをGitなどでバージョン管理をすれば、「なぜこのテーブルやカラムがあるのか?」という理由も残せるので安心です。