Migrations for existing project

I have updated SS version and mixed in support for migrations like described here:
https://docs.servicestack.net/ormlite/db-migrations#configuring-existing-projects
Then created two Migration1000 and Migration1001 classes (both inheriting from the MigrationBase database). The 1000 version have the original table, as it exists in the database, the 1001 version has the new table and uses Db.Migrate().

When I run dotnet run --AppTasks=migrate I get the following message: No AppTasks to run, exiting…

That message is when it’s already run all the migrations it can find, if you think it hasn’t run all migrations check the Migration table for what migrations have run which should have the logs for each run.

There is no Migration table.
Could it be that because the new Configure.Db.Migrations is using IHostingStartup, but the rest of the project, e.g. Configure.Db is : IConfigureServices, IConfigureAppHost, that it was never started?

oh the error message is that you haven’t got any AppTasks registered, check the docs for Configuring Existing Projects:

i.e. you should run:

$ x mix migrations

To create:

public class ConfigureDbMigrations : IHostingStartup
{
    public void Configure(IWebHostBuilder builder) => builder
        .ConfigureAppHost(afterAppHostInit:appHost => {
            var migrator = new Migrator(appHost.Resolve<IDbConnectionFactory>(), typeof(Migration1000).Assembly);
            AppTasks.Register("migrate", _ => migrator.Run());
            AppTasks.Register("migrate.revert", args => migrator.Revert(args[0]));
            AppTasks.Run();
        });
}

I have that file, but suspect that it might not be run, since it’s using the new IHostingStartup way, instead of the old ModularStartup?

Program.cs:

builder.UseModularStartup<Startup>();

Startup.cs:

public class Startup : ModularStartup

Then you need to configure it in your Program.cs as done with ASP .NET Core Projects:

var migrator = new Migrator(app.Services.Resolve<IDbConnectionFactory>(), typeof(Migrations.Migration1000).Assembly);
AppTasks.Register("migrate", _ => migrator.Run());
AppTasks.Register("migrate.revert", args => migrator.Revert(args[0]));
AppTasks.Run();

app.Run();
1 Like

Thanks, I’ll try that.

Then I can migrate my project later to the new style, as described here: https://docs.servicestack.net/modular-startup.html#migrating-to-hostingstartup

1 Like

The diff between versions doesn’t work for me

I got in configured in the Startup.cs file:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // the ASP.NET Core version you gave above, except for
    // app.ApplicationServices.Resolve that was modified:

    var migrator = new Migrator(app.ApplicationServices.Resolve<IDbConnectionFactory>(), typeof(Migrations.Migration1000).Assembly);
    AppTasks.Register("migrate", _ => migrator.Run());
    AppTasks.Register("migrate.revert", args => migrator.Revert(args[0]));
    AppTasks.Run();
}

Now the migrations run, however there is a problem with the initial migration, since I already have tables created before (with Db.CreateTableIfNotExists), so the declarative code first migrations doesn’t detect properly what to add.

Running AppTask 'migrate'...
Migrations Found:
 - Migration1000
 - Migration1001

Running Migration1000...

Completed Migration1000 in 0,040s

Running Migration1001...
SQL: ALTER TABLE "GrantUsernames" ADD COLUMN "Id" INTEGER NOT NULL;

ERROR: SQL logic error
duplicate column name: Id, Exception: SQL logic error
duplicate column name: Id

Migration1000.cs:

public class GrantUsernames
{
    [AutoIncrement]
    public int Id { get; set; }

    [References(typeof(ProcessInstance))]
    public int ProcessInstance { get; set; }

    public string Username { get; set; }

    public bool Create { get; set; }
    public bool Read { get; set; }
    public bool Update { get; set; }
    public bool Delete { get; set; }
}
public override void Up()
{
    Db.CreateTable<GrantUsernames>();
}

Migration1001.cs

public class GrantUsernames
{
    [AutoIncrement]
    public int Id { get; set; }

    [References(typeof(ProcessInstance))]
    public int ProcessInstance { get; set; }

    public string Username { get; set; }

    public bool Create { get; set; }
    public bool Read { get; set; }
    public bool Update { get; set; }
    public bool Delete { get; set; }

   public string Reason { get;set; } // the new column
}
public override void Up()
{
    Db.Migrate<GrantUsernames>();
}

However when run, 1000 is OK (does nothing), logged as OK in the Migration table, but 1001 tries to add the Id column. It doesn’t diff properly with the 1000.

That’s not how Migrate works, it doesn’t look at any previous migration class definitions, it only looks at the partial class definition it’s given where it adds new public properties as columns (by default) or remove/renames when annotated with their respective Alter column attributes.

So your new class should just be:

public class GrantUsernames
{
   public string Reason { get;set; } // the new column
}

Can you please annotate any c# code with:

```csharp
// C# code
```
1 Like