Fixed #23474 - Schema migrations can inadvertently destroy data

My usage of `get_migration_by_prefix` looks a bit funky, I'm not sure if there's a better way.

I haven't run the tests, or written any new tests yet.
There is lots of indexing here and it's unclear which of it is expected to throw the `KeyError`, so if we can move as much logic as possible out of the try/except that will help with readability.