it-swarm.com.ru

Соединение Rails 3.1 с несколькими базами данных

В ShowNearby мы выполняем очень большой переход на RoR 3.1 с PHP, и мы сталкиваемся с несколькими проблемами, которые, возможно, некоторые из вас уже решали ранее.

У нас есть большие объемы данных, и мы решили разделить нашу БД на несколько БД, которые мы можем обрабатывать отдельно. Например, наши учетные записи, места, журналы и другие разделены на несколько баз данных

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

  • одна модель должна относиться к одной таблице в одной из баз данных.
  • rake db: drop - удаляет всю базу данных env, которую мы указали в database.yml
  • rake db: create - должен создать всю базу данных env, которую мы указали в database.yml
  • rake db: migrate - должен выполнить миграцию в различные базы данных
  • rake db: test - должен захватывать приборы и помещать их в различные базы данных и тестировать модуль/функцию/и т. д.

Мы рассматриваем возможность установки отдельных проектов Rails для каждой базы данных и подключения их к ActiveResource, но считаем, что это не очень эффективно. Кто-нибудь из вас сталкивался с подобной проблемой раньше?

Спасибо!!

77
Fer Martin

Чтобы ответить на Wukerplank, вы также можете поместить данные о соединении в database.yml, как обычно, с таким именем:

log_database_production:
  adapter: mysql
  Host: other_Host
  username: logmein
  password: supersecret
  database: logs

Тогда в вашей специальной модели:

class AccessLog < ActiveRecord::Base
  establish_connection "log_database_#{Rails.env}".to_sym
end

Чтобы эти противные учетные данные не были в коде вашего приложения.

Редактировать: Если вы хотите повторно использовать это соединение в нескольких моделях, вам следует создать новый абстрактный класс и наследовать его, потому что соединения тесно связаны с классами (как объяснено здесь , здесь и здесь ), и для каждого класса будут созданы новые соединения.

Если это так, настройте вещи так:

class LogDatabase < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "log_database_#{Rails.env}".to_sym
end

class AccessLog < LogDatabase
end

class CheckoutLog < LogDatabase
end
142
Unixmonkey

Подключиться к различным базам данных довольно просто:

# model in the "default" database from database.yml
class Person < ActiveRecord::Base

  # ... your stuff here

end

# model in a different database
class Place < ActiveRecord::Base

  establish_connection (
    :adapter  => "mysql",
    :Host     => "other_Host",
    :username => "username",
    :password => "password",
    :database => "other_db"
  )

end

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

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

Консолидация БД в одну не вариант? Это сделало бы вашу жизнь намного проще!

18
Wukerplank

Нашел отличный пост, который укажет другим на правильный способ сделать эту проверку http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-Ruby.html знак равно

Настройте что-то вроде этого:

database.yml (файл конфигурации БД)

support_development:
    adapter: blah
    database: blah
    username: blah
    password: blah

support_base.rb (файл модели)

class SupportBase < ActiveRecord::Base
    self.abstract_class = true #important!
    establish_connection("support_development")
end

tst_test.rb (файл модели)

class TstTest < SupportBase 
    #SupportBase not ActiveRecord is important!

    self.table_name = 'tst_test'

    def self.get_test_name(id)
        if id = nil
            return ''
        else
            query = "select tst_name from tst_test where tst_id = \'#{id}\'"
            tst = connection.select_all(query) #select_all is important!
            return tst[0].fetch('tst_name')
        end
    end
end

PS, это на самом деле не распространяется на миграцию, я не думаю, что вы можете выполнять миграцию на более чем одной БД с помощью rake (хотя я не уверен, что это сложное "не может сделать", это может быть возможно). Это был просто отличный способ подключиться и запросить другие БД, которые вы не контролируете.

11
TwoByteHero

Возможно, вы также захотите добавить среду Rails, чтобы ваши базы данных для разработки и тестирования не совпадали.

establish_connection "legacy_#{Rails.env}"
5
Kris

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

Он также определяет знакомый db:migrate, который вызывает две другие задачи.

В том числе и здесь, если ссылка становится недоступной:

desc "Migrate the database through scripts in db/migrate directory."

namespace :db do
  task :migrate do
    Rake::Task["db:migrate_db1"].invoke
    Rake::Task["db:migrate_db2"].invoke
  end

  task :migrate_db1 do
    ActiveRecord::Base.establish_connection DB1_CONF
    ActiveRecord::Migrator.migrate("db/migrate/db1/")
  end

  task :migrate_db2 do
    ActiveRecord::Base.establish_connection DB2_CONF
    ActiveRecord::Migrator.migrate("db/migrate/db2/")
  end
end

Источник: Ruby on Rails Подключение к нескольким базам данных и миграциям

3
cweston

Эй, этот пост старый, но я нашел решение, работающее над Rails 3.2, которое может помочь кому-то еще. https://stackoverflow.com/a/16542724/1447654

1
Rafael