Работа одновременно с несколькими базами данных в Ruby on Rails
Обычно на сайте, в веб-приложении работа ведется с моделями (таблицы) одной базы данных. Но иногда возникает необходимость работать с несколькими базами данных одновременно, например, централизованная обработка данных нескольких источников (баз данных), распределенная система, система с резервным хранением данных и т.п.
В базовой конфигурации приложения Ruby on Rails такой возможности не предусмотрено, но это не значит, что такой возможности нет. Мало того, существует несколько способов.
Суть заключается в использовании метода класса ActiveRecord::Baseestablish_connection. Метод, как описано в документации, принимает хэш параметров соединения в качестве параметра. Но может быть так же передана и строка. Я использую MySQL, поэтому буду описывать параметры именно для работы с этой СУБД.
Способ 1
Как известно, конфигурация параметров соединения с базой данных (наименование базы данных, имя пользователя, пароль) хранится в файле config/database.yml, в котором прописаны параметры для каждого вида окружения, стадии разработки приложения - разработка, тестирование и готовая версия.
Но, что самое интересное, можно добавить собственный раздел в файл config/database.yml, например:
production:
adapter: mysql2
encoding: utf8
reconnect: false
database: dbname # основная база данных
pool: 5
username: user
password: pass1
socket: /var/run/mysqld/mysqld.sock
# далее наш дополнительный раздел:
another:
adapter: mysql2
encoding: utf8
reconnect: false
database: dbanother # другая база данных
pool: 5
username: user2
password: pass12
socket: /var/run/mysqld/mysqld.sock
И, собственно, ради чего все эти операции? Вот тут начинается самое интересное. Мы можем определить модель, которая будет использовать наше соединение (с другой базой данных):
class Another < ActiveRecord::Base
self.table_name = "mytable" # конечно, мы можем дополнительно
# уточнить и имя таблицы
self.establish_connection "another" # это наименование именно
# нашего раздела,
# описывающего соединение
...
end
Теперь, работая с нашей моделью Another, мы будем работать с базой данных dbanother, в то время как остальные модели все так же будут продолжать использовать основную базу dbname. Довольно удобно, не правда ли?
Для каждой стадии разработки мы точно так же можем создать собственный раздел нашей отдельной базы данных:
class Another < ActiveRecord::Base
...
# для использования различных версий
# на различных стадиях разработки:
self.establish_connection "another_#{Rails.env}"
...
end
Способ 2
Возможно указание параметров соединения непосредственно в определении модели:
class Another < ActiveRecord::Base
self.establish_connection(
:adapter => 'mysql2',
:host => 'localhost',
:database => 'dbanother',
:username => 'user2',
:password => 'pass12'
)
...
end
Способ 3
Возможно так же указание параметров соединения непосредственно перед использованием:
class Another < ActiveRecord::Base
...
end
...
# далее по коду, перед использованием
Another.establish_connection(
:adapter => 'mysql2',
:host => 'localhost',
:database => 'dbanother',
:username => 'user2',
:password => 'pass12'
)
...
@query = Another.limit(10).all
Таким образом, как можно видеть во 2 и 3 способах, возможно использовать довольно мощный механизм работы с произвольными базами данных, а не только одновременно работать с несколькими базами данных.
Обычно на сайте, в веб-приложении работа ведется с моделями (таблицы) одной базы данных. Но иногда возникает необходимость работать с несколькими базами данных одновременно, например, централизованная обработка данных нескольких источников (баз данных), распределенная система, система с резервным хранением данных и т.п.
В базовой конфигурации приложения Ruby on Rails такой возможности не предусмотрено, но это не значит, что такой возможности нет. Мало того, существует несколько способов.
Суть заключается в использовании метода класса
ActiveRecord::Base
establish_connection. Метод, как описано в документации, принимает хэш параметров соединения в качестве параметра. Но может быть так же передана и строка. Я использую MySQL, поэтому буду описывать параметры именно для работы с этой СУБД.Способ 1
Как известно, конфигурация параметров соединения с базой данных (наименование базы данных, имя пользователя, пароль) хранится в файле
config/database.yml
, в котором прописаны параметры для каждого вида окружения, стадии разработки приложения - разработка, тестирование и готовая версия.Но, что самое интересное, можно добавить собственный раздел в файл
config/database.yml
, например:И, собственно, ради чего все эти операции? Вот тут начинается самое интересное. Мы можем определить модель, которая будет использовать наше соединение (с другой базой данных):
Теперь, работая с нашей моделью
Another
, мы будем работать с базой данныхdbanother
, в то время как остальные модели все так же будут продолжать использовать основную базуdbname
. Довольно удобно, не правда ли?Для каждой стадии разработки мы точно так же можем создать собственный раздел нашей отдельной базы данных:
Изменим определение нашей модели:
Способ 2
Возможно указание параметров соединения непосредственно в определении модели:
Способ 3
Возможно так же указание параметров соединения непосредственно перед использованием:
Таким образом, как можно видеть во 2 и 3 способах, возможно использовать довольно мощный механизм работы с произвольными базами данных, а не только одновременно работать с несколькими базами данных.