Hi Nathaniel,
Others may reply to the part about writing an sbt plugin, etc, but what we have been doing on production and has worked well for at least 3 years is to have the db migration code all inside the actual app, instead of being delegated to an sbt task that you manually run.
Granted I didn't write it (All credit to Tim Nelson) , but iirc part of it includes what Matt Farmer did on this project
(which is great that he open sourced)
The way it works for us is:
1. Boot.scala we call a method on our Migration object, doMigrations()
2. doMigrations() gets the latest version of the running database (we have a table (we use Mongo so technically it's a collection, but it's the same for MySQl, let's call it a table from here on)) in this table, every time you run a migration, we add one row, with the description of the migration and then a numeric id, it's sequential, starting at 1.
3. Then we compare that to the latest migration number hard coded in our app, we have this on another object called MigrationVersion, a val called "latest"
so then we do something like:
(versionStoredOnDatabase+1 to latestVersionFromMigrationVersion).foreach { ver =>
ver is the version so here we use reflection to find the migration classes, run the,. save the migration id and description to the database so we don't run the migration twice, etc. I think this is where you will want to call flydb
}
so this will run every migration we have so that the database migration version matches the last one we added to our app.
And once the migration(s) are done, then Boot continues with the normal initialization and then our app is running again. No sbt needed, and it runs just fine locally in dev mode, on our staging, pilot and production servers.
In our case we have several web servers, so we run the migration on a dedicated server and then the rest of the app on the web servers continue to run, but I think you get the idea, if you need any more info on this way of handling migration, just let us know here.
Thanks
Diego