Machine.Migrations changes

Jacob first introduced Machine.Migrations over a year ago. Since then, it’s been a solid part of our process and we’re up to nearly 500 migrations with it on one project.

Recently, I finally got around to making some changes I’ve been wanting to make and I wanted to call’em out:

  • We split the repostiory out to its own on github. I did this similar to the way I did it for MSpec some time ago. Again, the advantage here is that change logs are localized to the project rather than the entire machine overarching project.
  • I added complaints if you have multiple migrations with the same number. This silently caused problems before as one of the migrations would not get applied. Now it just yells and dies like a good app. Of course, this is not as important because of the next change.
  • Next I added support for timestamped migrations. This helps immensely on active projects with multiple developers. You don’t have to deal with communicating migration numbers to the team when you add them, you just generate a new one and merge it when you feel like it. We actually had half of our topic on Campfire dedicated to our current migration number. The other half was who owed how many pushups for breaking the build.

    Here’s the rake task we use to generate a new migration:

    namespace :new do
      task :migration do
        raise "usage: rake new:migration name=\"Your migration name\"" unless ENV.include?('name')
        name = ENV['name']
        filepath = "db/migrate/#{'%Y%m%d%H%M%S')}_#{name.gsub(/ /,'_')}.cs"
        text ="db/migrate/template.cs"), 'w') { |file|
          file.puts text.gsub(/\$MigrationName\$/,"#{name.gsub(/ /,'_')}")

    Usage is simple, just create a template.cs in the directory (we use db/migrate) and then type

    rake new:migration name="this is my migration name"

    Example template:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Machine.Migrations;
    public class $MigrationName$ : SimpleMigration
      public override void Up()
        throw new System.NotImplementedException();
      public override void Down()
        throw new System.NotImplementedException();
  • Finally, I added a command line runner. As we’ve grown more and more sick of msbuild and more and more fond of rake, we’ve wanted to slowly all but eliminate our dependency on MSBuild. The command line tool is quite simple:

    Copyright (C) 2007, 2008, 2009 Machine Project
      c, connection-string  Required. The connection string to the database to migrate
      t, to                 Applies or unapplies migrations to get to the specified migration
      u, up                 Applies migrations to the latest
      s, scope              The scope?
      d, directory          Required. Directory containing the migrations
      v, compiler-version   Version of the compiler to use
      debug                 Show Diagnostics
      r, references         Assemblies to reference while building migrations separated by commas
      t, timeout            Default command timeout for migrations
      ?, help               Display this help screen

    The only two flags you usually need are -c and -d. Just pass in the connection string and the location of your migrations. Be sure to quote them: migrate.exe -c “my connection string” -d “my migration directory”.

  • Hopefully these changes help others. Grab the latest here and just msbuild the sln to build it.

    I do wonder though, what other active .NET migration projects are people using and how do you like them?

This entry was posted in machine, migrations. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Dan Ports

    At our company, we use a handrolled tool that uses timestamps and stores the SQL for the migrations in embedded resources. I looked at the available migrations tools for .NET a few years ago and wasn’t impressed with anything I saw, but perhaps I’ll take a look at Machine.Migrations.

  • Harry M

    Whoops, the link I added in my first post is wrong. SHould be

  • Harry M

    Hmm. In that case you may as well generate rollup and rolldown .sql along with the .cs file, and have the template CS file call out to them…

  • aaronjensen

    We actually just write sql. No fluent interfaces or anything… just execute sql calls. We messed w/ fluent intefaces, and doing NHibernate data migrations… but we decided it was too messy. We could probably get away w/ just using Ruby ActiveRecord migrations…

  • Harry M

    Myself and a few people I know at some other companies use my handrolled one. Its pretty similar to Tarantino, in that it uses sql instead of a c# api.

    I’ve found using c# to write migrations a bit of a pain compared to writing straight sql.