Database migrations where you are adding a field are easy. You can do the migration and then update the code to use the new field. If you know the migration will run before the code is deployed then you can even do this in a single PR. When you’re changing an existing field or removing a field or table you need to be more careful.

The best way to do this is in three phases. In the first you prepare your app to handle the current database schema and the one that you’ll be migrating to. Once that is in place you can do the actual migration, deploy, and verify everything is working. If something isn’t right you still have the old fields so you can roll back the deployment. When everything is good you can remove the code that supported the old schema.

This especially applies if your database is shared by more than one deployed system. Trying to co-ordinate releases and deployments is harder and more error prone than having the apps handle the before and after schema. It also allows you to do the migration at a low traffic time if necessary and not have to co-ordinate code releases.