Подключение Rails 3.1 с несколькими базами данных
В ShowNearby мы сделали очень большой переход на RoR 3.1 с PHP и столкнулись с несколькими проблемами, которые, возможно, некоторые из вас уже решали ранее.
У нас есть большие объемы данных, и мы решили разделить нашу БД на несколько БД, которые мы можем обрабатывать отдельно. Например, наши учетные записи, места, журналы и другие разделены на несколько баз данных
Нам нужно получить миграции, приспособления, модели, чтобы хорошо играть, и пока это было довольно грязно. Некоторые из наших требований для приемлемости решения:
- одна модель должна относиться к одной таблице в одной из баз данных.
- rake db: drop - удаляет все базы данных, которые мы указали в database.yml
- rake db: create - должен создать всю базу данных env, указанную в database.yml
- rake db: migrate - должен выполнить миграцию в различные базы данных
- rake db: test - следует захватить осветительные приборы и поместить их в различные базы данных и проверить модуль/функцию/etc
Мы рассматриваем возможность установки отдельных проектов rails для каждой базы данных и подключения их к ActiveResource, но считаем, что это не очень эффективно. Кто-нибудь из вас сталкивался с подобной проблемой раньше?
Ответы
Ответ 1
В ответ на 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
Ответ 2
Подключение к различным базам данных довольно просто:
# 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, поскольку вы добавили много накладных расходов на поиск данных для ваших контроллеров, что может замедлить работу.
Что касается ваших вопросов о миграциях, светильниках, моделях и т.д.: Я не думаю, что будет простой способ, поэтому, пожалуйста, размещайте отдельные вопросы и будьте как можно более конкретными.
Консолидация БД в один вариант не является опцией? Это сделало бы вашу жизнь намного проще!
Ответ 3
Нашел отличный пост, который укажет другим на правильный способ сделать это. http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-ruby.html
Настройте что-то вроде этого:
database.yml(файл конфигурации db)
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, это действительно не распространяется на миграцию, я не думаю, что вы можете выполнять миграции более чем на одной БД с граблями (хотя я не уверен, что это трудно "не могу", возможно, это возможно), Это был просто отличный способ подключить и запросить другие БД, которые вы не контролируете.
Ответ 4
Вы также можете добавить среду Rails, поэтому ваши базы разработки и тестирования не совпадают.
establish_connection "legacy_#{Rails.env}"
Ответ 5
следующая статья предлагает определить новые задачи 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 Подключение к нескольким базам данных и миграции
Ответ 6
Эй, этот пост старый, но я нашел решение, работающее над Rails 3.2, которое может помочь кому-то другому.
fooobar.com/info/74323/...