Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run migration script every time

I have a particular DB script that needs to run as the last migration script and it needs to run every time I run migrations on a DB (even if it's been run before).

I can use a very large migration ID to ensure that this migration runs last. However, I don't know what to do to force re-running this migration every time: once it runs, it gets added to the dbo.VersionInfo table and the next time FluentMigrator sees it in that table, it doesn't run it again.

[Migration ( 209912312359 )]
public class M209912312359 : Migration
{
    public override void Down ()
    {
        // I want this particular migration to always run
        // as the last migration script and to run every time.
    }
}

Is there some kind of migration attribute that tells FluentMigrator to run this script every time regardless of previous runs? (The Migration base class doesn't have anything to override for this.)

I'm using FluentMigrator 1.4.

Edit:

This is a data migration that cleans up some data in the database. At work we have a large number of databases (same schemas, different data). One particular table (let's call it dbo.A) must have the same data in the same order in all databases. We add data to this table using migrations but sometimes - depending on what migrations run in a particular DB - instances of dbo.A may get out of sync.

The purpose of this migration is to make sure all instances of dbo.A contain the same data in the same order. We cannot drop dbo.A and just recreate it because its ID column is used as a foreign key.

I'd like to have a migration solution, if possible, because migrations are the only thing that are guaranteed to run in all of our environments as part of deployment and changing this would be very hard. (If FluentMigrator cannot do this, we probably don't have a choice.)

like image 740
xxbbcc Avatar asked Feb 10 '23 00:02

xxbbcc


2 Answers

Just use the [Maintenance(MigrationStage.AfterAll)] attribute as below and it will always run the Up() method:

using FluentMigrator;
using System;

namespace Example
{
    [Maintenance(MigrationStage.AfterAll)]
    public class RefreshAllViews : FluentMigrator.Migration
    {
        public override void Up()
        {
            Execute.Sql(@"
                DECLARE views_cursor CURSOR FOR
                SELECT name FROM sysobjects WHERE type = 'V' AND uid = 1
                OPEN views_cursor

                DECLARE @view NVARCHAR(500)
                FETCH NEXT FROM views_cursor INTO @view
                WHILE @@FETCH_STATUS = 0
                BEGIN
                    BEGIN TRY
                        EXEC sp_refreshview @view
                    END TRY
                    BEGIN CATCH
                        PRINT 'VIEW NAME: ' + @view + 
                              ', ERROR NUMBER: ' + Cast(ERROR_NUMBER() as VARCHAR) + 
                              ', ERROR MESSAGE: ' + ERROR_MESSAGE()
                    END CATCH
    
                    FETCH NEXT FROM views_cursor INTO @view
                END

                CLOSE views_cursor
                DEALLOCATE views_cursor");
        }

        public override void Down()
        {
            throw new NotImplementedException();
        }
    }
}
like image 191
KillerKiwi Avatar answered Feb 14 '23 11:02

KillerKiwi


To solve your problem I just created an abstract class that implements the method Down and inherit this on your new Migrations classes.

public abstract class MigrationBase : FluentMigrator.Migration
{
    public override void Down()
    {
        //Do what you want for every migration
    }
}

[FluentMigrator.Migration(209912312359)]
public class M209912312359 : MigrationBase
{
    public override void Up()
    {
        //New migration...
    }
}
like image 24
hdias2310 Avatar answered Feb 14 '23 10:02

hdias2310