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

时间:2008-09-17 07:41:29

标签: ruby-on-rails ruby activerecord

情况就是这样。

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

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

我该怎么做?

谢谢,
卷帘

3 个答案:

答案 0 :(得分:9)

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

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

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

相同

ActiveRecord::Base.establish_connection documentation

然后你可以使用

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

执行你的sql查询。

ActiveRecord::Base.find_by_sql documentation

Mr Matt如果不完整则是正确的

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

答案 1 :(得分:6)

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

  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并在完成后丢弃该对象。

答案 2 :(得分:0)

您可以通过self.establish_connection

执行此操作