【问题标题】:using activerecord with nested databases在嵌套数据库中使用 activerecord
【发布时间】:2013-07-14 07:23:05
【问题描述】:

我正在构建一个 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

【问题讨论】:

    标签: ruby-on-rails database activerecord model


    【解决方案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。

    【讨论】:

    • 感谢您的想法...我最终只是在每个连接模型上创建了一个实例方法,该方法使用 Sequel gem 返回一个连接。这样数据库就不需要在 database.yml 中预先定义。但我会接受你的回答!
    • @user1609682 感谢您接受(我希望它可以帮助您找到自己的解决方案)!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-26
    相关资源
    最近更新 更多