2008-10-15 7 views
9

Je dois apporter des modifications à une base de données de production en cours d'utilisation. Juste en ajoutant quelques colonnes. J'ai apporté les modifications à la base de données dev avec les migrations. Quel est le meilleur moyen de mettre à jour la base de données de production tout en préservant les données existantes sans trop perturber le fonctionnement?Rails: Meilleure façon d'apporter des modifications à une base de données de production

C'est MYSQL et je vais devoir ajouter des données aux colonnes pour les enregistrements déjà existants. Une colonne peut avoir une valeur par défaut (c'est un booléen) mais l'autre est un horodatage et devrait avoir une valeur antidatée arbitraire. Le nombre de lignes n'est pas énorme. Donc, si j'utilise les migrations, comment puis-je ajouter des données et comment puis-je obtenir les deux (ou trois - j'ajoute les migrations de données - les plus récentes sur la production db quand elle n'était pas initialement créée via les migrations (I ? croient qu'ils ont utilisé le schéma à la place)

Répondre

6

On dirait que vous êtes dans un état où le schéma db de production doesn Ne correspond pas exactement à ce que vous utilisez en Dev (bien que ce ne soit pas totalement clair). Je tracerais une ligne dans le sable et je ferais en sorte que ce prod soit dans un meilleur état. Essentiellement, ce que vous voulez faire est de vous assurer que la base de données prod db a une table "schema_info" qui répertorie toutes les migrations que vous ne voulez jamais exécuter en production. Ensuite, vous pouvez ajouter des migrations à votre contenu de coeurs et ils vont travailler contre la production DB.Une fois cela fait, vous pouvez écrire des migrations qui ajoutent des modifications de schéma ou ajouter des données, mais une chose dont vous devez faire attention est que si vous ajoutez des données en utilisant une migration, vous devez définir le modèle dans la migration. lui-même, comme ceci:

class AddSomeColumnsToUserTable < ActiveRecord::Migration 
    class User < ActiveRecord::Base; end 
    def self.up 
    add_column :users, :super_cool, :boolean, :default => :false 
    u = User.find_by_login('cameron') 
    u.super_cool = true 
    u.save 
    end 

    def self.down 
    remove_column :users, :super_cool 
    end 
end 

la raison est que, dans l'avenir, vous pouvez supprimer le modèle tout à fait, pendant une refactorisation ou autre. Si vous ne définissez pas la classe d'utilisateurs sur la ligne "User.find_by_login ...", la migration va générer une exception, ce qui est très pénible.

4

est-il une raison que vous n'utilisez pas les mêmes migrations que vous avez utilisé dans votre environnement dev

+2

La base de données est déjà utilisée, donc je ne veux pas perdre les données existantes et je préférerais ne pas avoir à prendre le temps de reconstruire et de repeupler si je peux l'éviter. – srboisvert

+0

Donc, la migration est destructive? Ou utilisez-vous actuellement des migrations, mais vous ne les avez jamais utilisées en production, et vous tenterez donc de faire * toutes * les migrations, dont certaines sont plus anciennes et ne sont plus pertinentes et pourraient donc causer des problèmes? – Matt

+0

Pouvez-vous décrire, dans votre question, qu'en est-il de vos migrations qui les rendent destructrices? Cela pourrait aider à obtenir une réponse plus précise à votre problème. – Matt

2

Ajout d'une colonne avec add_column dans une migration devrait être non destructive: il sera générer une instruction "ALTER TABLE" Si vous savez ce que vous allez mettre dans les colonnes une fois créées, vous pouvez remplir les valeurs dans la migration (vous pouvez choisir une alternative moins longue si la ligne compte Arge).

La suppression ou la modification de la définition d'une colonne dépend, selon moi, de la plateforme: certaines autoriseront la suppression d'une colonne, d'autres exécuteront une séquence de commandes rename-create-select-drop. Pour plus de précision, nous avons besoin de plus d'informations: quel type de migration envisagez-vous, sur quelle plate-forme travaillez-vous, avez-vous besoin de définir des valeurs dans le cadre de la migration? Des trucs comme ça aideraient beaucoup - il suffit d'éditer la question, qui la repoussera dans la liste.

14

Je suis toujours cette procédure:

  • base de données prod Dump avec mysqldump commande
  • Populate base de données dev/test avec vidage en utilisant la commande mysql
  • migrations Run dans dev/test
  • migration de vérification a travaillé
  • Dump prod base de données avec la commande mysqldump (car il peut avoir changé) en gardant la sauvegarde sur le serveur
  • Exécuter des migrations sur prod (en utilisant capristano)
  • de migration test a travaillé sur prod
  • boire de la bière (tout en regardant les journaux d'erreur)
+0

Est-ce que vous faites toutes les étapes non capistrano et non bière manuellement? On dirait beaucoup de place pour une bonne automatisation/scripting? – dolzenko

+0

Les trois premières étapes sont scriptées. Les contrôles sont une combinaison de tests automatisés et de tests manuels. Les tests manuels se concentrent surtout sur les domaines que je connais ont changé. Je pousse seulement pour aiguillonner une fois toutes les quelques semaines. – RichH