On dirait que sqlalchemy.migrate ne prend pas en charge le rendu d'une requête valide en cas de modification des types de colonne String en Integer pour postgresql.
Dans votre cas, je l'implémenterais en tant qu'exécution de requête directe et je passerais à autre chose.
def downgrade(migrate_engine):
# ALTER TABLE courses ALTER COLUMN number SET DATA TYPE integer;
migrate_engine.execute('ALTER TABLE courses ALTER COLUMN number TYPE INTEGER USING number::numeric')
BTW la migration de String vers Integer peut échouer pour différentes raisons - lorsque la valeur de la colonne contiendrait une valeur qui ne peut pas être convertie en nombre. J'ajouterais donc une validation supplémentaire dans la logique de l'application pour que la migration vers une version antérieure reste possible ultérieurement.