0

我正在构建一个 Rails 应用程序来存储许多不同的、用户提供的数据库连接,并对每个连接执行任意 sql。我将每个数据库连接字符串表示为“连接”模型的一个实例,并希望能够编写一个方法来查询每个连接表示的数据库,最好使用 activerecord ORM。但是,当我在以下代码中使用建立连接方法时,我编写的代码会覆盖整个连接表的数据库连接。您如何建议我更改代码以查询任意数据库,而不覆盖整个 Connections 表的连接?

class Connection < ActiveRecord::Base
  validates_presence_of :host, :port, :db_name, :db_user, :db_password, :db_type

  def connect
    self.connection = ActiveRecord::Base.establish_connection(
      adapter: self.db_type,
      host: self.host,
      database: self.db_name,
      username: self.db_user,
      password: self.db_password
    )
  end

end
4

1 回答 1

1

一个很好的方法是为您需要的每个数据库连接创建一个模型,然后将其他模型作为它们的子类。因此,例如:

  1. 在 database.yml 中定义所有需要的连接(每个环境)
    # DB 1
    development:
      adapter: mysql2
      encoding: utf8
      database: db_1
      username: ****
      password: ****
      host: ********
      pool: 5
      ...

    # DB 2
    db2_development:
      adapter: mysql2
      encoding: utf8
      database: db_2
      username: ****
      password: ****
      host: ********
      pool: 5
      ...

    # Same for production (and/or other environments)
    production:
      ...
    db2_production:
      ...
  1. 为每个数据库定义一个“主”模型,该模型继承自ActiveRecord::Base
    # DB1
    class DB1 < ActiveRecord::Base
      self.abstract_class = true
    end

    # DB2
    class DB2 < ActiveRecord::Base
      self.abstract_class = true
      establish_connection "db2_#{Rails.env}"
    end

    ...
  1. 现在将所有特定于数据库的模型定义为上面定义的模型的子类,以这种方式:
    # DB1 specific model
    class DB1_model < DB1
      # model logic here
    end

    # DB2 specific model
    class DB2_model < DB2
       # model logic here
    end

    ...

你可以走了。

通过这种方式,您可以连接到不同环境中的 N 个数据库(通常是developmentstagingpreprodproduction,但在您的情况下它们可能会有所不同)。

另外,请记住 Rails 将为每个数据库管理一个 SQL 连接池。

在上面的示例中,Rails 将为每个数据库打开最多5 个连接,因此总数将为10(对于应用程序的单个实例)。如果您使用 Phusion Passenger 或 Unicorn,并生成 8 个应用程序实例,总 SQL 连接数将(最大)为 10*8 = 80。

于 2013-07-14T08:26:14.430 回答