Rails: Est-ce mauvais d’avoir une migration irréversible?

Quand est-il acceptable de générer une exception ActiveRecord :: IrreversibleMigration dans la méthode de migration automatique? Quand devriez-vous faire l’effort d’implémenter le contraire de la migration?

Si vous avez affaire à des systèmes de production, alors oui, c’est très mauvais. Si c’est votre propre projet animalier, alors tout est permis (sinon, ce sera une expérience d’apprentissage 🙂 mais il y a des chances que tôt ou tard, même dans un projet animalier, vous vous retrouviez avec un croisement. inverser la migration pour devoir annuler cette migration quelques jours plus tard, que ce soit par rake ou manuellement.)

Dans un scénario de production, vous devez toujours faire un effort pour écrire et tester une migration réversible dans l’éventualité où vous la parcourriez en production, puis découvrez un bogue qui vous oblige à restaurer (code et schéma) une révision précédente (en attente). un correctif non sortingvial – et un système de production par ailleurs inutilisable.

Les migrations inversées vont du plus sortingvial (suppression des colonnes ou des tables ajoutées lors de la migration et / ou modification des types de colonnes, etc.) à un peu plus complexe ( execute de JOIN ed INSERT ou UPDATE s), mais rien n’est trop complexe. justifier “le balayer sous le tapis”. À tout le moins, vous forcer à réfléchir aux moyens de réaliser des migrations inversées peut vous donner un nouvel aperçu du problème que votre migration vers l’avance est en train de résoudre.

Vous pouvez parfois rencontrer une situation où une migration vers l’extérieur supprime une fonctionnalité, ce qui entraîne le rejet des données de la firebase database. Pour des raisons évidentes, la migration inverse ne peut pas ressusciter les données supprimées. Bien que l’on puisse, dans de tels cas, recommander que la migration vers l’extérieur sauvegarde automatiquement les données ou les conserve dans l’éventualité d’une restauration en tant que solution alternative à l’échec complet (enregistrer en yml , copier / déplacer vers une table spéciale, etc.) pas besoin, car le temps nécessaire pour tester une telle procédure automatisée pourrait dépasser le temps requirejs pour restaurer les données manuellement (le cas échéant). Mais même dans de tels cas, au lieu de simplement échouer , vous pouvez toujours faire l’inverse. Échec de la migration conditionnelle et temporaire en attente d’une action de l’utilisateur (test de l’existence d’une table obligatoire à restaurer manuellement; en cas d’absence, échec car je ne parviens pas à recréer la table XYZ lance-moi encore et je ne te manquerai pas! “)

Si vous détruisez des données, vous pouvez en faire une sauvegarde en premier. par exemple

 def self.up # create a backup table before destroying data execute %Q[create table backup_users select * from users] remove_column :users, :timezone end def self.down add_column :users, :timezone, :ssortingng execute %Q[update users U left join backup_users B on (B.id=U.id) set U.timezone = B.timezone] execute %Q[drop table backup_users] end 

Dans un scénario de production, vous devez toujours faire un effort pour écrire et tester une migration réversible dans l’éventualité où vous la parcourriez en production, puis découvrez un bogue qui vous oblige à restaurer (code et schéma) une révision précédente (en attente). un correctif non sortingvial – et un système de production par ailleurs inutilisable.

Avoir une migration réversible convient parfaitement au développement et à la mise en scène, mais en supposant un code bien testé, il devrait être extrêmement rare que vous souhaitiez migrer en production. J’intègre dans mes migrations une migration automatique irréversible en mode production. Si j’avais vraiment besoin d’inverser un changement, je pourrais utiliser une autre migration “up” ou supprimer l’exception. Cela semble cependant sommaire. Tout bogue qui provoquerait un scénario désastreux est un signe que le processus d’assurance qualité est sérieusement foutu.

Sentir que vous avez besoin d’une migration irréversible est probablement un signe que vous avez de plus gros problèmes à venir. Peut-être que certains détails aideraient?

En ce qui concerne votre deuxième question: je prends toujours l’effort pour écrire l’inverse des migrations. Bien sûr, je n’écris pas le .down , TextMate l’insère automatiquement lors de la création du .up .

La migration de données réversible facilite la création de migrations de données réversibles à l’aide de fichiers yaml.

 class RemoveStateFromProduct < ActiveRecord::Migration def self.up backup_data = [] Product.all.each do |product| backup_data << {:id => product.id, :state => product.state} end backup backup_data remove_column :products, :state end def self.down add_column :products, :state, :ssortingng restore Product end end 

IIRC, vous aurez la migration Irreversible lors de la modification d’un type de données dans la migration.

Je pense qu’une autre situation, quand ça va, c’est quand vous avez une migration consolidée. Dans ce cas, un “down” n’a pas vraiment de sens, car il laisserait tomber toutes les tables (à l’exception des tables ajoutées après la consolidation). Ce n’est probablement pas ce que vous voudriez.