连接Rails 3.1与多个数据库

Fer*_*tin 77 ruby ruby-on-rails activeresource ruby-on-rails-3 rails-activerecord

在ShowNearby,我们一直在从PHP迁移到RoR 3.1,我们面临着一些问题,可能是你们之前已经解决过的问题.

我们有大量数据,我们决定将数据库分成几个可以单独处理的数据库.例如,我们的帐户,地点,日志和其他帐户被拆分为多个数据库

我们需要让迁移,固定装置,模型,以及良好的发挥,到目前为止它已经相当混乱.我们对解决方案的一些要求是可以接受的:

  • 一个模型应该与一个数据库中的一个表相关.
  • rake db:drop - 应该删除我们在database.yml中指定的所有数据库env
  • rake db:create - 应该创建我们在database.yml中指定的所有数据库环境
  • rake db:migrate - 应该运行迁移到各种数据库
  • rake db:test - 应该抓住fixture并将它们放入各种数据库和测试单元/功能/等

我们正在考虑为每个数据库设置单独的rails项目并将它们与ActiveResource连接,但我们认为这不是非常有效.你们之前有没有遇到过类似的问题?

非常感谢!!

Uni*_*key 142

对于Wukerplank的回答,您还可以像往常一样将连接详细信息放在database.yml中,其名称如下:

log_database_production:
  adapter: mysql
  host: other_host
  username: logmein
  password: supersecret
  database: logs
Run Code Online (Sandbox Code Playgroud)

然后在你的特殊模型中:

class AccessLog < ActiveRecord::Base
  establish_connection "log_database_#{Rails.env}".to_sym
end
Run Code Online (Sandbox Code Playgroud)

保持那些讨厌的凭据不在您的应用程序代码中.

编辑:如果要在多个模型中重用此连接,则应创建一个新的抽象类并从中继承,因为连接与类紧密耦合(如此,此处此处所述),并且将创建新的连接每节课.

如果是这种情况,请设置如下:

class LogDatabase < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "log_database_#{Rails.env}".to_sym
end

class AccessLog < LogDatabase
end

class CheckoutLog < LogDatabase
end
Run Code Online (Sandbox Code Playgroud)

  • 预先警告.似乎使用此方法会打开其他数据库上的连接而不重用它们.这将使您的应用程序在重负载下停止运行. (12认同)
  • @Altonymous好点.我认为你指的是这种行为:https://github.com/rails/rails/issues/7019连接与课程相关联; 所以如果你需要重用连接,你应该在抽象类上建立它并从它继承而不是AR :: Base.我更新了我的答案以反映这一点. (10认同)

Wuk*_*ank 18

连接到不同的数据库非常简单:

# model in the "default" database from database.yml
class Person < ActiveRecord::Base

  # ... your stuff here

end

# model in a different database
class Place < ActiveRecord::Base

  establish_connection (
    :adapter  => "mysql",
    :host     => "other_host",
    :username => "username",
    :password => "password",
    :database => "other_db"
  )

end
Run Code Online (Sandbox Code Playgroud)

我会担心设置多个Rails项目,因为你会为控制器的数据检索增加很多开销,这可能会让事情变得缓慢.

至于你关于迁移,固定装置,模型等的问题:我不认为会有一个简单的方法,所以请发布单独的问题并尽可能具体.

将DB合并为一个不是一个选项?它会让你的生活更轻松!

  • 问题是上面的示例无法正确使用连接池 (2认同)

小智 11

找到一篇很棒的文章,指出其他人正确的方式来做这个检查 http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-ruby.html

设置如下:

database.yml(db配置文件)

support_development:
    adapter: blah
    database: blah
    username: blah
    password: blah
Run Code Online (Sandbox Code Playgroud)

support_base.rb(模型文件)

class SupportBase < ActiveRecord::Base
    self.abstract_class = true #important!
    establish_connection("support_development")
end
Run Code Online (Sandbox Code Playgroud)

tst_test.rb(模型文件)

class TstTest < SupportBase 
    #SupportBase not ActiveRecord is important!

    self.table_name = 'tst_test'

    def self.get_test_name(id)
        if id = nil
            return ''
        else
            query = "select tst_name from tst_test where tst_id = \'#{id}\'"
            tst = connection.select_all(query) #select_all is important!
            return tst[0].fetch('tst_name')
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

PS,这真的不包括迁移,我不认为你可以使用rake在多个DB上进行迁移(虽然我不确定那是一个很难'不能做',但这可能是可能的).这只是连接和查询您无法控制的其他DB的好方法.


Kri*_*ris 5

您可能还想附加Rails环境,因此您的开发和测试数据库不一样.

establish_connection "legacy_#{Rails.env}"
Run Code Online (Sandbox Code Playgroud)