【问题标题】:ActiveRecord 3.1.0 multiple databasesActiveRecord 3.1.0 多数据库
【发布时间】:2011-09-12 15:54:47
【问题描述】:

我正在尝试将 ActiveRecord gem 升级到最新的 3.1.0 版本并看到很多异常出现,我认为这是由于我们处理多个数据库的方式。

对于我们的每个数据库,我们指定一个单独的基类,它继承自ActiveRecord::Base,并在其中调用establish_connection。没有跨数据库关系。到目前为止,这对我们来说效果很好。

升级到 ActiveRecord 3.1.0 我看到它在遍历关系时失败并出现ActiveRecord::ConnectionNotEstablished 异常(即,它将成功从数据库中提取单个实体或一组实体,但导航到相关类)。

回溯的第一行是C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.1.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:410:in 'retrieve_connection',所以我对此进行了一些研究。方法定义如下:

def retrieve_connection(klass) #:nodoc:
    pool = retrieve_connection_pool(klass)
    (pool && pool.connection) or raise ConnectionNotEstablished
end

我的简单测试 (puts Customer.first.address) 调用了 retrieve_connection 3 次。两次使用Customer 作为klass 参数,一次使用ActiveRecord::Base 作为参数 - 这是因为establish_connection 没有为ActiveRecord::Base 调用而失败。

实际问题 那么 - 是否有一种新的推荐方法可以在 ActiveRecord 中处理多个数据库连接?如果有,是什么?

如果不是,是什么导致了这个问题?

【问题讨论】:

    标签: ruby activerecord


    【解决方案1】:

    我昨天在升级到 ActiveRecord 3.1.0 时遇到了同样的问题。我不知道在 ActiveRecord 3.1 中是否有一种新的推荐方法来处理多个数据库连接,但我确实找到了一种解除阻塞的方法。

    现在看来必须在 ActiveRecord::Base 上建立一个连接,以便它确定适配器的表名长度/规则。除了在我的数据库初始化程序中建立的其余连接外,我现在还建立了一个与我的一个 DB 的 ActiveRecord::Base 连接(不管是哪个数据库)。

    我想找到更好的解决方案,但我很高兴现在可以畅通无阻。

    【讨论】:

    • 感谢您,还没有时间尝试,但听起来是个不错的解决方案!如果您找到更好的方法,请回来告诉我们...
    • 我们遇到了同样的问题,希望找到更好的解决方案。不过,感谢您的帮助。至少我们现在也解封了!
    • 我自己遇到了这个问题(activerecord 3.1.3)并按照建议解决了这个问题。我同意更好的解决方案会更理想。
    【解决方案2】:

    我正在使用这个解决方案 - 我看到的是,当在每个 OtherDb 类中调用建立连接时 - 似乎有很多开销重新加载表定义,并且每次重新加载类 def 时我都会随机看到问题。

    # The idea here is to specify that a given model should use another
    # database without having to change the entire inheritance hierarchy
    
    # declare model for table in primary connection
    class Bar < ActiveRecord::Base
      # assume we have logic here that we don't want to refactor into a module
      # but we do want to inherit in OtherDb::Bar
    end
    
    module Foo
    
      # base model in Foo namespace - uses another db
      class BaseConnection < ActiveRecord::Base
        # OtherDb::Title.database contains a db config hash
        # This would probably go in the initializers
        establish_connection OtherDb::Title.database 
      end
    
      # module used to override db connection
      module OtherDb::Base
        def retrieve_connection
          # connection_handler.retrieve_connection(self) #  normal behavior
          connection_handler.retrieve_connection(Foo::BaseConnection) # use db from Foo::BaseConnection
        end
      end
    
      # Foo::Bar is identical to ::Bar but is in another db
      class Bar < ::Bar
        extend OtherDb::Base
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-20
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多