Vladimir Plaksa
Vladimir Plaksa

Reputation: 21

How to force FluentMigrator to run migration even if DB version matches

I use FluentMigrator 3.2.1 & dotnet-fm too to run migrations. Imagine that I have database versions 1,2,3,4 and so on, classes are marked with

[FluentMigrator.Migration(1, "1")]
 [FluentMigrator.Migration(2, "2")]
 [FluentMigrator.Migration(3, "3")]
 [FluentMigrator.Migration(4, "4")]

and all of them have overriden Up() and Down() methods. While in dev env, I have DB version 4. I modify "up" script with a new version of a stored procedure. Database already has version 4 in VersionInfo table, and I execute this command

dotnet-fm migrate -p Postgres -c "Server=192.168...server info" -a "/mnt/d/src/........DB.dll" up

I would like the migrator to do "force" update to the version 4 again, but looks like is sees that version of the DB is already 4. I use to rollback to 3 and the roll forward to the latest, but it is not convenient and is not suitable for CI/CD. Is there any elegant way to "force" the "up" migration, f.ex. with migration tags?

Upvotes: 2

Views: 2292

Answers (1)

John Zabroski
John Zabroski

Reputation: 2357

I am one of the co-maintainers of FluentMigrator. This isn't something supported by the framework, but there is a workaround as well as a way to think about how to architect your build process.

Workaround

psql

The simplest workaround would be to use psql to delete the latest migration:

psql -U username -h 192.160.128.101 -d mydatabase -c 'DELETE FROM VersionInfo WHERE Id = 4'

bash wrapper for psql

You could use bash and create an function for this command. Note, you have to create a function if you want to make this command accept a parameter.

fm-rm()
{
  # THIS DOES NO ERROR CHECKING.
  # DO NOT RUN THIS AGAINST A PRODUCTION SERVER.
  psql -U username -h $1 -d $2 -c 'DELETE FROM VersionInfo WHERE Id = $3'
}

You can then just do:

fm-rm localhost MyDatabase 4

powershell extensions for FluentMigrator

Further, if you use PowerShell, you can write a similar script and use PowerShell's powerful auto-complete to speed up typing this out. Someone recently started a VisualStudio PowerShell project to do something like this, but it's not very robust just yet. See: https://github.com/crimcol/FluentMigrator.VStudio You would write Rollback-FluentDatabase 4

Best Practice

If you are running these migrations in your development environment, then what you want is a workflow for creating a test database and then running migrations against that test database.

From the command line arguments you provided in your example, it looks like you are using a non-Windows environment and using PostgreSql. An alternative solution, that I want to add samples for, is TestEnvironment.Docker and spinning up a SQL Server Container via docker. (Unfortunately, SqlLocalDb isn't available on Linux and you're using PostgreSql. On Windows, SqlLocalDb would be the ideal lightweight solution for spinning up test servers and test databases.)

If you're using MSBuild, you can also define a TestSetup target that sets up a DatabaseName_UnitTest database. When I do this, I have a baseline CreateSchema.sql that runs, creates a database and the schema as of a point-in-time, and then I apply all migrations. In this way, I can gaurantee the release process should work, especially if I'm using a GitFlow-like release model, where I only deploy out of master branch.

Upvotes: 2

Related Questions