I’m not sure what to say to that. In the former (database changes belong to a different team), there’s not much that can be helped.
Given the number of people—on HN, no less—who have war stories about having accidentally dropped the production database because of insufficient protections and the desire of many businesses to know that their vendors are following SOC2 and similar safety and security protocols, I completely get that.
In the latter case (availability risk), there’s no sympathy I can provide. Developers need to be aware of what their changes mean. Sometimes this means that you make a separate table. Sometimes it means you have a downtime event which means an overnight deploy. Sometimes it means you have to figure out how to do a zero-downtime series of migrations.
Step 0: make sure you need the migration.
Step 1: modify the app to conditionally query or update the new column based on whether the change is present or not, and without requiring a value in the column. (Since it’s not, this will work as an `if false` case for now.) Deploy.
Step 2: modify the database to add the column with no constraints (safe and trivial on most SQL databases). Deploy.
Step 3: modify the app to start filling in fields that should not be null. (That is, provide constraint validation at the application level; or, if dropping a column, start setting the value to a least damaging value or NULL if you could have made a required field no longer required.) Deploy.
Step 4: After some time, run a backfill to fill in new required values (or clear old values) that haven’t been modified yet. If you’ve done this right, it should be a small number. Optionally, do this periodically for small subsets of data.
Step 5: Run a final backfill and deploy a schema migration that adds your constraint/drops your column (dropping a column is optional if you’ve got a hard zero downtime requirement; just make sure no one tries to use it and make sure it’s not part of the application schema; schema comments are your friend).
Step 6: Deploy a version of the app that doesn’t act conditionally.
Yes, it takes longer. I’ve run migrations this way for the last seven years and we’ve had essentially _no_ downtime because of migrations. I think we’ve had ~4 hours of preventative downtime across ~10 databases in that time. Usually, when we’re ready for the piece that can cause downtime…there’s about a five minute hiccup.
Developers who can’t reason through safe table alterations shouldn’t be making those changes, and PlanetScale is going to make some business people very unhappy when their developer changes something that they didn’t actually understand and causes downtime regardless of PS’s “guarantees”.