2013-05-14 55 views
3

我们有一个主数据库,我们所有的应用程序驻留在这里。从第二个数据库中提取数据的有效方法?

但还有第二个数据库(从外部来源更新),我希望能够连接到,所以我可以从中获取数据。我不需要写任何东西......只是阅读。

它也只有一张桌子,我拉。

我真的只是需要做一些事情,如:

OtherDatabase.articles.where(id > 1000) 

就是这样。

那么我怎么能在Rails(运行3.2.13)中做到这一点?

+0

请注意,如果您确实在意不写入现有数据库,则应使用仅授予有限读取权限的凭据进行连接。 I.E.,不要依赖此应用程序的代码来强制执行其他应用程序的权限。 – 2016-01-16 06:59:52

回答

16

对于简单的场景,Rails可以支持这个,不需要任何额外的宝石;只需在database.yml中定义数据库:

other_db: 
    adapter: mysql2 
    encoding: utf8 
    database: other_db 
    username: user 
    password: passwd 
    host: 1.2.3.4 
    port: 3306 

然后在模型中要使用其他数据库中添加:

class Article < ActiveRecord::Base 
    establish_connection(:other_db) 
    self.table_name = 'other_db.articles' 
end 

然后你就可以进行查询:

Article.where("id > 1000") 

=)

+2

我得到它的工作后,我意识到两种方法的论点是不同的。您需要发送'establish_connection(:other_db)'连接名称,这是database.yml示例的第一行。但'self.table_name ='other_db.articles''需要真正的数据库名称,它是database.yml的第4行。 – taiansu 2015-01-29 08:35:16

0

复制/粘贴:

对于单主机的情况下,你可以定义为读取从站database.yml的另一个数据库连接:

read_slave: 
    adapter: postgresql 
    database: read_only_production 
    username: user 
    password: pass 
    host: read_slave_host 

该数据库由一个模块,支持其镜子使用此数据库连接ActiveRecord的类:

require 'magic_multi_connections' 
module ReadSlave 
    establish_connection :read_slave 
end 

现在,所有预先存在的模型可以通过添加前缀的read_slave连接访问模型类与ReadSlave ::。

# use the read-only connection 
    @user = ReadSlave::User.find(params[:id]) 

    # write to the master (can't use @user.update_attributes because it would# 
    try to write to the read slave) 
    User.update(@user.id, :login => "new_login") 
3

首先,我们需要定义外部数据库:

# config/database.yml 
external: 
    adapter: sqlite3 
    database: db/external.sqlite3 
    pool: 5 
    timeout: 5000 

对于这样的事情,我更喜欢使用一个处理数据库连接的模块。

# lib/database.rb 
module Database 
    def self.using(db, klass=ActiveRecord::Base) 
    klass.establish_connection(db.to_sym) 
    result = yield if block_given? 
    klass.establish_connection(Rails.env.to_sym) 
    result 
    end 
end 

通过传递一个块模块这样我们可以确保我们不流血我们查询到,他们不属于或忘记回复我们的连接的数据库。另外,我们默认使用ActiveRecord :: Base,以便我们可以使用我们的任何模型。但是,如果我们知道我们只使用一个并且想要隔离我们的模型使用情况,我们可以将其作为次要参数传递。

所得的实现可以是这个样子:

# app/models/user.rb 
class User < ActiveRecord::Base 
    def read_remote 
    Database.using(:external) do 
     account = Account.where(active: true) 
     account.users 
    end 
    end 
end 

现在我们有一个非常干净的块中,我们可以在任何地方使用我们喜欢的,用任何我们想要的模型块内始终在extneral进行操作数据库。一旦该块完成,我们知道我们正在回到我们的原始数据库。

+0

由于'Account'总是连接到相同的数据库(在OP的情况下),似乎过度使用。但它看起来像是一种将单个模型连接到多个数据库的有趣方法。 – davogones 2013-05-23 05:58:00

相关问题