Is it possible to use fluent migrator in application_start?
Asked Answered
B

2

47

I'm using fluent migrator to manage my database migrations, but what I'd like to do is have the migrations run at app start. The closest I have managed is this:

public static void MigrateToLatest(string connectionString)
{
    using (var announcer = new TextWriterAnnouncer(Console.Out)
                                {
                                    ShowElapsedTime = true,
                                    ShowSql = true
                                })
    {
        var assembly = typeof(Runner).Assembly.GetName().Name;

        var migrationContext = new RunnerContext(announcer)
        {
            Connection = connectionString,
            Database = "SqlServer2008",
            Target = assembly
        };

        var executor = new TaskExecutor(migrationContext);
        executor.Execute();
    }
}

I'm sure I had this working, but I've not looked at it for sometime (hobby project) and it's now throwing null reference exceptions when it gets to the Execute line. Sadly there are no docs for this and I've been banging my head on it for ages.

Has anyone managed to get this kind of thing working with FluentMigrator?

Bruis answered 27/9, 2011 at 19:7 Comment(5)
I'm going on record here: Bad Idea. Tying deployments/migrations into the start of your app? Madness. What's the app going to do if a migration fails? Not start?Venturesome
@jcollum: is the app likely to run if it's expecting the migrated database? Failing at startup is the right answer.Fortify
@insta Hardly. You should immediately roll back an app that has failed its migration. The app shouldn't be aware of what version it is in, it should just run the version it has.Venturesome
What about for testing? Generating an empty database to perform integration or acceptance tests against. That's a valid and useful scenario.Auscultate
It's a few years down the line, but what I now do is: Build server runs sql migrations (redgate tools), if they fail the build reverts, if not they continue and deploy the software. This is the same for qa, live etc. Locally the dev team use redgate sql source control. It's proving to be a stable way of working.Bruis
A
63

PM> Install-Package FluentMigrator.Tools

Manually add a reference to:

packages\FluentMigrator.Tools.1.6.1\tools\AnyCPU\40\FluentMigrator.Runner.dll

Note that the folder name will vary on version number, this illustration uses the current 1.6.1 release. If you need the .NET 3.5 runner use the \35\ directory.

public static class Runner
{
    public class MigrationOptions : IMigrationProcessorOptions
    {
        public bool PreviewOnly { get; set; }
        public string ProviderSwitches { get; set; }
        public int Timeout { get; set; }
    }

    public static void MigrateToLatest(string connectionString)
    {
        // var announcer = new NullAnnouncer();
        var announcer = new TextWriterAnnouncer(s => System.Diagnostics.Debug.WriteLine(s));
        var assembly = Assembly.GetExecutingAssembly();

        var migrationContext = new RunnerContext(announcer)
        {
            Namespace = "MyApp.Sql.Migrations"
        };

        var options = new MigrationOptions { PreviewOnly=false, Timeout=60 };
        var factory = 
            new FluentMigrator.Runner.Processors.SqlServer.SqlServer2008ProcessorFactory();

        using (var processor = factory.Create(connectionString, announcer, options))
        { 
            var runner = new MigrationRunner(assembly, migrationContext, processor);
            runner.MigrateUp(true);
        }
    }
}

Note the SqlServer2008ProcessorFactory this is configurable dependent upon your database, there is support for: 2000, 2005, 2008, 2012, and 2014.

Alar answered 9/5, 2012 at 0:19 Comment(7)
I was getting an error that TextWriterAnnouncer does not implement IDisposable so you can't use a using on it. This was on the latest version of FluentMigratorBroadway
For anyone installing FluentMigrator from NuGet, FluentMigrator.Runner is in tools, and not referenced by default.Gurnard
FluentMigrator.Runner is in the FluentMigrator too. Under packages, there's a tools dir (this is as of v1.1.1.0.Auscultate
As of 1 year ago there was a change that removed IDisposable from TextAnnouncer. Instead, dispose the IMigrationProcessor if you are getting file in use errors.Basin
Is it possible that this approach does not configure conventions correctly? Eg: Foreign Key NameModernism
Do not forget to install "FluentMigrator.Tools" package, this is separate item on Nuget (because default package has only x86 runner and will fail with BadImageFormatException at AnyCPU projects.Clarethaclaretta
I have a query if there are the bunch of file to migration and suddenly there is an error while this code process (one file ) and I want to that if any error then it will go to next fileFormate
E
5

I have actually accomplished running migrations in the application_start however it is hard to tell from that code what could be wrong... Since it is open source I would just grab the code and pull it into your solution and build it to find out what the Execute method is complaining about. I found that the source code for Fluent Migrator is organized pretty well.

One thing that you might have to be concerned about if this is a web app is making sure that no one uses the database while you are migrating. I used a strategy of establishing a connection, setting the database to single user mode, running the migrations, setting the database to multi user mode, then closing the connection. This also handles the scenario of a load balanced web application on multiple servers so 2 servers don't try to run migrations against the same database.

Edgar answered 30/9, 2011 at 15:58 Comment(2)
interesting approach to play with single user mode and multiple in order to run a migration.Voroshilovgrad
In case of scenario of a load balanced web application on multiple servers: you could create a step in octopus that runs migrations on every server before deployment.Periodicity

© 2022 - 2024 — McMap. All rights reserved.