I have a similar approach, but with timestamps instead of an incremental int.
I'd use a tool for this, but then I would need to change how I deploy the apps given that usually, it's best to run the migrations and then update the codebase to prevent exceptions.
In case there are new columns, the best solution would be: execute the migrations (if there are new columns, make them NULL), deploy the code, fill the new columns via SQL or code, if the new columns must be not-NULL, change the table definition and make the columns not-NULL.
Given the complexity I find better to do it by hand.
Yeah, timestamps seem to work much better, especially with distributed version control. Otherwise you have to coordinate who gets the next number in the sequence. There's still a race condition between two branches changing the schema in incompatible ways, but with a clean merge. But in my experience, code review, tests, and just developers running migrations day-to-day mitigates that issue.
I'd use a tool for this, but then I would need to change how I deploy the apps given that usually, it's best to run the migrations and then update the codebase to prevent exceptions.
In case there are new columns, the best solution would be: execute the migrations (if there are new columns, make them NULL), deploy the code, fill the new columns via SQL or code, if the new columns must be not-NULL, change the table definition and make the columns not-NULL.
Given the complexity I find better to do it by hand.