Migrations, like a changescript, should be able to be run repeatedly. This means defensive coding; checking if columns or tables exist before doing operations. Or, if necessary, dropping and recreating.
In many cases, migration order doesn’t matter, at least in the short term. But when the order matters, then the ordering should be explicit and controlled by the user.
Use list / ordering instead of numbering, which puts the burden on users to handle numbers, and having to deal with collisions and difficult merges because of this.
Hashing of migrations can be automatic, and allow migrations to be re-run automatically if the hash has changed.