In StackOverflow we used an in-house db framework where we ran external .sql scripts in a sqlmigrations folder and maintained the state of which scripts were called in a
migrations RDBMS table. We’d then run a generic script which runs all non-executed sql scripts that don’t already exist in the
migrations table. We’d run this script locally to update our local development RDBMS schema whilst the CI Server would run it automatically before deploying to UAT/Production so the scripts are always run (and RDBMS state kept in-sync with App) before deployment.
But for myself I’m currently maintaining all db migrations in a Unit test (ordered sequentially and alphabetically with naming convention prefix) which I run manually from VS.NET/R# with a flag property to indicate which RDBMS connection the migration scripts should be run against. I prefer writing migrations with C# and OrmLite since a lot of cases I’m usually doing more than just modifying the schema, e.g. adding/modifying/transforming existing data which I prefer to write in C# than SQL.
Eventually I’d like to formalize a proposed simple solution like the above that makes use of a
migrations state table so you could rerun a generic command to execute all migrations and it would only run any new migrations (i.e. tetsts) in alphabetical order. I wouldn’t consider a 3rd party framework myself because I don’t feel any friction with my current solution that would justify introducing and learning a 3rd party tool. The noticeable thing any of the db migration solutions are missing is the ability to rollback a deploy where IMO the additional effort for maintaining compensating logic for each migration is not worth it for the few times you’d rollback deploys in production. It’s easier to just “push ahead” with a new deploy with a new migration script fixing any bugs/issues from the previous one.