в Rails, как мне выполнить прямой SQL-код в другой базе данных?

StackOverflow https://stackoverflow.com/questions/80859

Вопрос

Вот такой случай.

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

Базы данных, к которым мне нужно подключиться, неизвестны во время разработки (т. е.:Я не могу поместить их данные в database.yaml).Скорее, у меня есть модель "database_details", которую пользователь будет использовать для ввода сведений о базах данных, по которым приложение будет выполнять запросы во время выполнения.
Таким образом, подключение к этим базам данных действительно является динамическим, и детали разрешаются только во время выполнения.

Как я могу это сделать?

Спасибо,
Ролло

Это было полезно?

Решение

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

  def get_custom_connection(identifier, host, port, dbname, dbuser, password)
      eval("Custom_#{identifier} = Class::new(ActiveRecord::Base)")
      eval("Custom_#{identifier}.establish_connection(:adapter=>'mysql', :host=>'#{host}', :port=>#{port}, :database=>'#{dbname}', " +
      ":username=>'#{dbuser}', :password=>'#{password}')")  
    return eval("Custom_#{identifier}.connection")
  end

Это имеет дополнительное преимущество в том, что вы не изменяете ваше соединение ActiveRecord ::Base, от которого наследуются ваши модели, поэтому вы можете запустить SQL для этого соединения и удалить объект, когда закончите с ним.

Другие советы

Вы можете программно установить соединение, используя подобный вызов

ActiveRecord::Base.establish_connection(
   :adapter  => "mysql",
   :host     => "localhost",
   :username => "myuser",
   :password => "mypass",
   :database => "somedatabase"
)

Как вы видите, вы можете заменить somedatabase значением database_model.database_name.то же самое с adatpter и всем прочим

ActiveRecord::Документация Base.establish_connection

Тогда вы можете использовать

ActiveRecord::Base.find_by_sql("select * ") 

чтобы выполнить ваш sql-запрос.

ActiveRecord::Документация Base.find_by_sql

Мистер Мэтт был прав, хотя и неполон

Более подробную информацию (устаревшую, но все еще полезную для данного подхода к проектированию) можно найти здесь и не забудьте повторно подключиться к обычной базе данных, когда закончите :)

Возможно, вы сможете сделать это с помощью self.установить_соединение

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top