Использование Rails Migration для другой базы данных, отличной от стандартных «производство» или «разработка» - PullRequest
46 голосов
/ 10 сентября 2009

У меня запущен проект rails, который определяет стандартную продукцию :,: development и: test DB-подключений в config / database.yml

Кроме того, у меня есть определение quiz_development: и quiz_production: определение, указывающее на другой хост / db / user / password

Моя цель теперь состоит в том, чтобы определить миграцию, которая использует "quiz_#{RAILS_ENV}` "в качестве конфигурации базы данных.

Что я пробовал (и не получилось):

  • Настройка ActiveRecord :: Base.connection в файле миграции
  • Изменение задачи db: migrate в rails для установки там ActiveRecord :: Base.connection

Вопрос:

Как заставить rake db: migrate использовать другое определение базы данных?

Спасибо, Frank

Ответы [ 19 ]

2 голосов
/ 01 декабря 2011

В дополнение к выполнению миграции в другой среде, я также хочу схемы в отдельных файлах. Вы можете сделать это из командной строки:

RAILS_ENV=quiz_development SCHEMA=db/schema_quiz_development.rb rake db:migrate

Но мне нравится подход с пользовательскими граблями, поэтому я могу ввести его вместо:

rake db:with[quiz_development, db:migrate]

Вот задание на грабли:

namespace :db do
  desc "Run :task against :database"
  task :with, [:database,:task] => [:environment] do |t, args|
    puts "Applying #{args.task} to #{args.database}"
    ENV['SCHEMA'] ||= "#{Rails.root}/db/schema_#{args.database}.rb"
    begin
      oldRailsEnv = Rails.env
      Rails.env = args.database
      ActiveRecord::Base.establish_connection(args.database)
      Rake::Task[args.task].invoke
    ensure
      Rails.env = oldRailsEnv
    end
  end
end
2 голосов
/ 29 октября 2015

Я нашел отличный способ сделать это:

class CreateScores < ActiveRecord::Migration

  class ScoresDB < ActiveRecord::Base
    establish_connection("scores_#{Rails.env}")
  end

  def connection
    ScoresDB.connection
  end

  def up
    create_table :scores do |t|
      t.text :account_id
      t.text :offer
    end
  end

  def down
    drop_table :scores
  end
end
1 голос
/ 09 сентября 2015

Вы можете использовать эту версию, которая также поддерживает rake db:rollback:

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

  def reset_connection
    ActiveRecord::Base.establish_connection(Rails.env)
  end

  def up
    # make changes

    reset_connection
  end

  def self.down
    # reverse changes

    reset_connection
  end
end
1 голос
/ 02 июня 2014
class Article < ActiveRecord::Base

    ActiveRecord::Base.establish_connection(
      :adapter  => "mysql2",
      :host     => "localhost",
      :username => "root",
      :database => "test"
    )
end

И

class Artic < Aritcle
    self.table_name = 'test'

    def self.get_test_name()
        query = "select name from testing"
        tst = connection.select_all(query) #select_all is important!
        tst[0].fetch('name')
    end
end

Вы можете вызвать Artic.get_test_name для выполнения.

0 голосов
/ 13 июня 2013

На основании ответа @ TheDeadSerious:

module ActiveRecord::ConnectionSwitch  
  def on_connection(connection_spec_name)
    raise ArgumentError, "No connection specification name specified. It should be a valid spec from database.yml" unless connection_spec_name
    ActiveRecord::Base.establish_connection(connection_spec_name)
    yield
  ensure
    ActiveRecord::Base.establish_connection(Rails.env)
  end
end

ActiveRecord.send :extend, ActiveRecord::ConnectionSwitch

Использование:

ActiveRecord.on_connection "sdmstore_#{Rails.env}" do
  Widget.delete_all
end
0 голосов
/ 14 сентября 2009

Вы также можете переместить все ваши миграции, связанные с quiz_, в отдельную подпапку в каталоге db /, а затем добавить задачи rake, отражающие функции обычной миграции, но при этом выполняется поиск миграции в этом подкаталоге. Не супер-элегантно, возможно, но это работает. Вы можете копировать и вставлять грабли, уже находящиеся в рельсах, и просто немного их изменять.

0 голосов
/ 02 июня 2014

, если вы хотите отобразить сообщение WordPress на вашем сайте и Вы не хотите использовать много-магический драгоценный камень соединения. Вы можете использовать приведенный ниже код для получения данных из блога WordPress.

 class Article < ActiveRecord::Base

    ActiveRecord::Base.establish_connection(
     :adapter  => "mysql2",
     :host     => "localhost",
     :username => "root",
     :database => "blog"
    )

    self.table_name = 'wp_posts'

    def self.get_post_data()
        query = "select name from testing"
        tst = connection.select_all(query)
        tst[0].fetch('name')
    end
end
0 голосов
/ 28 декабря 2017

Я получил эту работу, создав отдельные классы коннекторов для разных баз данных и используя их в миграциях.

class AddExampleToTest < ActiveRecord::Migration
  def connection
    @connection = OtherDatabaseConnector.establish_connection("sdmstore_#{Rails.env}").connection
  end
  def up
    add_column :test, :example, :boolean, :default => true

    @connection = MainDatabaseConnector.establish_connection("#{Rails.env}").connection
  end
  def down
    remove_column :test, :example

    @connection = MainDatabaseConnector.establish_connection("#{Rails.env}").connection
  end
end

Мы можем определить эти классы соединителей в инициализаторах.

class MainDatabaseConnector < ActiveRecord::Base
end
class OtherDatabaseConnector < ActiveRecord::Base
end

ActiveRecord :: Base поддерживает пул соединений, который является хешем, проиндексированным классом. Подробнее здесь . Поэтому использование отдельных классов для отдельных соединений защищает нас от ошибки закрытого соединения.

Кроме того, использование up и down вместо change позволяет откатить миграцию без каких-либо проблем. До сих пор не выяснил причину этого.

0 голосов
/ 14 сентября 2009

Вы пытались использовать quiz_development в качестве RAILS_ENV (вместо того, чтобы заставить его использовать "quiz_#{RAILS_ENV}")?

RAILS_ENV=quiz_development rake db:migrate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...