We do this. It has worked very well for us.
There's a couple of fundamental rules to follow. First, don't put something that will have insane impact into the application deploy changes. 99% of the DB changes are very cheap, and very minor. If the deploy is going to be very expensive, then just don't do it, we'll do it out of band. This has not been a problem in practice with our 20ish person team.
Second, it was kind of like double entry accounting. Once you committed the change, you can not go back and "fix it". If you did something really wrong (i.e. see above), then sure, but if not, you commit a correcting entry instead. Because you don't know who has recently downloaded your commit, and run it against their database.
The changes are a list of incremental steps that the system applies in order, if they had not been applied before. So, they are treated as, essentially, append only.
And it has worked really well for us, keeping the diverse developers who deploy again local databases in sync with little drama.
I've incorporated the same concept in my GUI programs that stand up their own DB. It's a very simple system.