I'm currently trying to implement Migrations withing Umbraco but a problem occurs when i try to run multiple migrations. The migrations should run while installing a package so in the installer file that is called from Umbraco.
So I got a package with a migration in it. If it is installed the migration runs fine. But when I install a newer version of the package the new migration doesn't run. The MigrationRunner is initialized as stated in the log files. But nothing happens.
Migrations:
[Migration("2.0.1", 0, "UpdateEventCalendarTables")]
public class EventMigration : MigrationBase
{
public override void Down()
{
Delete.Column("categories").FromTable("ec_events");
}
public override void Up()
{
Alter.Table("ec_events").AddColumn("categories").AsString(255).Nullable();
}
}
[Migration("2.0.1", 1, "UpdateEventCalendarTables")]
public class RecEventMigration : MigrationBase
{
public override void Down()
{
Delete.Column("categories").FromTable("ec_recevents");
}
public override void Up()
{
Alter.Table("ec_recevents").AddColumn("categories").AsString(255).Nullable();
}
}
[Migration("2.0.2", 0, "UpdateEventCalendarTables2.0.2")]
public class CalendarTextColorMigration : MigrationBase
{
public override void Down()
{
Delete.Column("textcolor").FromTable("ec_calendars");
}
public override void Up()
{
Alter.Table("ec_calendars").AddColumn("textcolor").AsString(255).Nullable();
}
}
And here is how i call them in the newest package installer:
try
{
var runner = new MigrationRunner(this.oldVersion, this.newVersion, "UpdateEventCalendarTables");
var upgraded = runner.Execute(this._db, true);
LogHelper.Info<installer>("Done doing migration for version 2.0.1" + upgraded.ToString());
}
catch (Exception ex) { LogHelper.Error<installer>("Failed to do the migration for a version", ex); }
try
{
var runner = new MigrationRunner(this.oldVersion, this.newVersion, "UpdateEventCalendarTables2.0.2");
var upgraded = runner.Execute(this._db, true);
LogHelper.Info<installer>("Done doing migration for version 2.0.2" + upgraded.ToString());
}
catch (Exception ex) { LogHelper.Error<installer>("Failed to do the migration for a version", ex); }
You changed the "ProductName" from "UpdateEventCalendarTables" to "UpdateEventCalendarTables2.0.2", so the migration runner will treat them as two different products. Meaning that you're 3 different migrations are essentially targeted at two different packages instead of one.
If you want all 3 migrations to be run for the same package you should keep the same "ProductName" throughout.
thanks for your answer. Tryed to name give it the same "ProductName" but that's also not working.
The first migration for version 2.0.1 is already run and if i then install the new package with the same migration and the new one for 2.0.2 then the last one doesn't get executed.
Maybe I miss understand how the migrations are executed with the version number.
The first run is when current version is 2.0.0 and the new one is 2.0.1. Thats the migration that works.
Next migration is for 2.0.1 to 2.0.2 and that doesn't work but I execute the runner for both migrations.
The migrations should target the version that you are upgrading to. So if 2.0.2 is the latest version and you want to bring a 2.0.0 package up-to-date the way you target the migrations sounds right. When the migration runner is initialized with from version: 2.0.0 and to version 2.0.2 it will look for all migrations (with the specified product name) which are larger then 2.0.0 and smaller then or equal to 2.0.2.
Now if you install the package with version 2.0.2 and you have to run the migrations to update an existing install it could be that the migrations haven't been found yet. As far as I remember they are found at startup, so you might need to either recycle the app pool or pass in the migrations to run (disclaimer: can't remember if this is currently possible).
you're right, the Update from 2.0.0 to 2.0.2 is working fine. Every migration gets resolved.
But from 2.0.1 to 2.0.2 the second and new migration doesn't get resolved.
I thought that is maybe because of the same name the migration have, but I'm not sure,
I think I have an idea for how to get around the issue of the latest migrations not being included, but it requires an update in the Core as the MigrationRunner is not quite flexible enough.
We have an event for when the MigrationRunner is 'Migrating' and when its done 'Migrated', but currently its an IEnumerable which you can't change. The point of this event was to allow package developers to inject additional migrations to run.
With the changes in this commit https://github.com/umbraco/Umbraco-CMS/commit/3af3e054d7da078ea4ad8b936f15a313bea368d3 you will be able to specify all the migrations to filter (up-front) or use the Migrating event to add additional migrations to the list. You will be able to use this in the installer, but unfortunately it won't be able until 7.1.5 is out.
Glad I pointed out some usefull changes to the core by producing an issue. Waiting for 7.1.5 is ok for me, meanwhile I can do some other work for the package.
Using multiple migrations on package install
Hey all,
I'm currently trying to implement Migrations withing Umbraco but a problem occurs when i try to run multiple migrations. The migrations should run while installing a package so in the installer file that is called from Umbraco.
So I got a package with a migration in it. If it is installed the migration runs fine. But when I install a newer version of the package the new migration doesn't run. The MigrationRunner is initialized as stated in the log files. But nothing happens.
Migrations:
And here is how i call them in the newest package installer:
Anybody knows what to do?
Hi David,
You changed the "ProductName" from "UpdateEventCalendarTables" to "UpdateEventCalendarTables2.0.2", so the migration runner will treat them as two different products. Meaning that you're 3 different migrations are essentially targeted at two different packages instead of one.
If you want all 3 migrations to be run for the same package you should keep the same "ProductName" throughout.
- Morten
Hi Morten,
thanks for your answer. Tryed to name give it the same "ProductName" but that's also not working.
The first migration for version 2.0.1 is already run and if i then install the new package with the same migration and the new one for 2.0.2 then the last one doesn't get executed.
Maybe I miss understand how the migrations are executed with the version number.
The first run is when current version is 2.0.0 and the new one is 2.0.1. Thats the migration that works.
Next migration is for 2.0.1 to 2.0.2 and that doesn't work but I execute the runner for both migrations.
David
The migrations should target the version that you are upgrading to. So if 2.0.2 is the latest version and you want to bring a 2.0.0 package up-to-date the way you target the migrations sounds right. When the migration runner is initialized with from version: 2.0.0 and to version 2.0.2 it will look for all migrations (with the specified product name) which are larger then 2.0.0 and smaller then or equal to 2.0.2.
Now if you install the package with version 2.0.2 and you have to run the migrations to update an existing install it could be that the migrations haven't been found yet. As far as I remember they are found at startup, so you might need to either recycle the app pool or pass in the migrations to run (disclaimer: can't remember if this is currently possible).
- Morten
Ah, looks like there is no good way of specifying exactly which migrations to run instead of the default resolving part:
https://github.com/umbraco/Umbraco-CMS/blob/7.1.0/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs#L49
We should probably improve that.
- Morten
Hi Morten,
you're right, the Update from 2.0.0 to 2.0.2 is working fine. Every migration gets resolved. But from 2.0.1 to 2.0.2 the second and new migration doesn't get resolved.
I thought that is maybe because of the same name the migration have, but I'm not sure,
Thanks for youre help thus far.
David
Hi Morten, as we have talked at CodeGarden here is the link to the github repository of my package. https://github.com/Mantus667/EventCalendarBelle/blob/development/EventCalendarBelle/Migrations/TargetVersionTwo.cs Thats the direct link to where I set the migrations.
The runner is called on package install.
Hope that helps to reproduce the issue and get some ideas about it.
Thanks David
Hi David,
I think I have an idea for how to get around the issue of the latest migrations not being included, but it requires an update in the Core as the MigrationRunner is not quite flexible enough. We have an event for when the MigrationRunner is 'Migrating' and when its done 'Migrated', but currently its an IEnumerable which you can't change. The point of this event was to allow package developers to inject additional migrations to run.
With the changes in this commit https://github.com/umbraco/Umbraco-CMS/commit/3af3e054d7da078ea4ad8b936f15a313bea368d3 you will be able to specify all the migrations to filter (up-front) or use the Migrating event to add additional migrations to the list. You will be able to use this in the installer, but unfortunately it won't be able until 7.1.5 is out.
Hope this helps,
Morten
Hi Morten,
sorry for answering that late.
Glad I pointed out some usefull changes to the core by producing an issue. Waiting for 7.1.5 is ok for me, meanwhile I can do some other work for the package.
Thanks for coming back to me with this solution.
David
is working on a reply...