在Rails中,如何在不同的数据库上执行直接SQL代码?

Rol*_*zzi 5 ruby activerecord ruby-on-rails

情况就是这样.

我正在编写一个Rails应用程序,它将监视某些特定数据库的数据质量.为了做到这一点,我需要能够在这些数据库上执行直接的SQL查询 - 这当然与用于驱动Rails应用程序模型的数据库不同.简而言之,这意味着我无法使用通过ActiveRecord基本连接的技巧.

我需要连接的数据库在设计时是不知道的(即:我不能将它们的详细信息放在database.yaml中).相反,我有一个模型'database_details',用户将使用该模型输入应用程序将在运行时执行查询的数据库的详细信息.
因此,与这些数据库的连接确实是动态的,并且细节仅在运行时解析.

我怎样才能做到这一点?

谢谢,
罗洛

Jea*_*ean 10

您可以使用这样的调用以编程方式建立连接

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

如您所见,您可以使用database_model.database_name值替换somedatabase.与adatpter和所有相同

ActiveRecord :: Base.establish_connection文档

然后你可以使用

ActiveRecord::Base.find_by_sql("select * ") 
Run Code Online (Sandbox Code Playgroud)

执行你的SQL查询.

ActiveRecord :: Base.find_by_sql文档

如果不完整,马特先生是对的

可以在此处找到更多信息(过时但对设计方法仍然有用)并记住在完成后重新连接到普通数据库:)


小智 7

我有这样的情况,我不得不连接到外部应用程序的数百个不同的实例,我做了类似于以下的代码:

  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
Run Code Online (Sandbox Code Playgroud)

这样做的另一个好处是不会更改模型继承的ActiveRecord :: Base连接,因此您可以针对此连接运行SQL并在完成后丢弃该对象.