48 votes

Utilisation de Rails Migration sur une base de données différente de la base standard "production" ou "développement".

J'ai un projet rails en cours d'exécution qui définit les connexions DB standard production :, :development et :test dans config/database.yml.

De plus, j'ai une définition de quiz_development : et de quiz_production : qui pointe vers un hôte/db/utilisateur/mot de passe différent.

Mon objectif est maintenant de définir une migration qui utilise " quiz_#{RAILS_ENV }" comme configuration de sa base de données.

Ce que j'ai essayé (et échoué) :

  • Définition de ActiveRecord::Base.connection dans le fichier Migration
  • Modification de la tâche db:migrate dans rails pour y définir ActiveRecord::Base.connection

Question :

Comment puis-je faire en sorte que rake db:migrate utilise cette autre définition de base de données ?

Merci, Frank

36voto

Bryan Larsen Points 2630

Il y a une réponse beaucoup plus simple. Ajoutez ceci à votre migration :

def connection
  ActiveRecord::Base.establish_connection("quiz_#{Rails.env}").connection
end

C'est pour Rails 3.1. Pour Rails 2.X ou 3.0, il s'agit plutôt d'une fonction de classe (ex. def self.connection )

18voto

Marlin Pierce Points 5558

J'ai réussi à le faire fonctionner avec le code suivant.

class AddInProgressToRefHighLevelStatuses < ActiveRecord::Migration
  def connection
    @connection = ActiveRecord::Base.establish_connection("sdmstore_#{Rails.env}").connection
  end

  def change
    add_column :ref_high_level_statuses, :is_in_progress, :boolean, :default => true

    @connection = ActiveRecord::Base.establish_connection("#{Rails.env}").connection
  end
end

Il a fallu rétablir la connexion pour qu'il écrive la migration dans la table schema_migrations afin que rake n'essaie pas de ré-exécuter la migration la prochaine fois. Cela suppose que vous souhaitez que la table schema_migrations dans la configuration par défaut de la base de données garde la trace des migrations enregistrées dans le contrôle de version pour le projet correspondant.

Je n'ai pas réussi à faire fonctionner la migration descendante.

15voto

Bitterzoet Points 1758

Vous devez définir les autres bases de données/environnements dans /config/environnements.

Après cela, vous pouvez utiliser la commande suivante pour migrer cet environnement spécifique.

rake db:migrate RAILS_ENV=customenvironment

11voto

Siu Points 52

Un peu tard, mais j'ai été confronté à ce problème aujourd'hui et j'ai trouvé cette tâche de râteau personnalisée :

namespace :db do
  desc "Apply db tasks in custom databases, for example  rake db:alter[db:migrate,test-es] applies db:migrate on the database defined as test-es in databases.yml"
  task :alter, [:task,:database] => [:environment] do |t, args|
    require 'activerecord'
    puts "Applying #{args.task} on #{args.database}"
    ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[args.database])
    Rake::Task[args.task].invoke
  end
end

8voto

Rafael Points 121

J'ai creusé cette question pendant quelques jours et j'ai fini par trouver cette solution. Je voulais juste la partager, elle pourrait aider quelqu'un.

Voici l'essentiel de ce qu'il faut savoir. https://gist.github.com/rafaelchiti/5575309 Il y a des détails et des explications. Mais trouvez ci-dessous plus de détails si vous en avez besoin.

L'approche est basée sur l'ajout d'un espace de nom aux tâches rake déjà connues db:migrate, db:create, db:drop et d'exécuter ces tâches avec une base de données différente. Et ensuite en ajoutant une classe de base d'enregistrement actif (AR) pour la connexion basée sur la configuration du nouveau fichier database.yml. De cette façon, vous n'avez pas besoin de bidouiller les migrations avec des trucs de connexion et vous obtenez une structure de répertoire propre.

Votre structure se terminera comme suit

config
  |- database.yml
  \- another_database.yml (using the same nomenclature of 'development', 'test', etc).

db
  |- migrate (default migrate directory)
  |- schema.rb
  |- seed.rb

another_db
  |- migrate (migrations for the second db)
  |- schema.rb (schema that will be auto generated for this db)
  |- seed.rb (seed file for the new db)

Ensuite, dans votre code, vous pouvez créer une classe de base et lire la configuration de ce nouveau fichier database.yml et vous y connecter uniquement sur les modèles qui héritent de cette classe de base AR. (exemple dans le gist).

Le meilleur !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X