Rails中的多个数据库

能做到吗? 在单个应用程序中,使用SQLite管理多个项目。我要为我的应用程序正在管理的每个项目都拥有一个不同的数据库..因此,一个结构相同的数据库有多个副本,但是其中有不同的数据。 我将选择基于URI的参数使用哪个副本。

这样做是为了1.安全性。我是这种编程的新手,并且我不希望由于某种原因而在进行一个项目时发生这种情况,而另一个项目则被损坏。.2.易于备份和存档 旧项目

luca asked 2020-01-24T02:53:45Z
8个解决方案
39 votes

默认情况下,Rails不是为多数据库体系结构设计的,并且在大多数情况下,它根本没有任何意义。但是可以,您可以使用其他数据库和连接。

这里是一些参考:

  • ActiveRecord:连接到不同模型的多个数据库
  • Ruby on Rails中的多个数据库连接
  • 魔术多连接
Simone Carletti answered 2020-01-24T02:54:14Z
27 votes

如果您能够控制和配置每个Rails实例,并且由于资源处于待机状态而浪费资源,那么您可以省下麻烦,只需更改database.yml即可修改每个实例上使用的数据库连接。 如果您担心性能,这种方法将无法解决问题。

对于仅在一个数据库上绑定到单个唯一表的模型,您可以在模型内部调用Establishment_connection:

establish_connection "database_name_#{RAILS_ENV}"

如此处所述:[http://apidock.com/rails/ActiveRecord/Base/ Establishment_connection / class]

您将拥有一些模型,这些模型使用来自一个数据库的表,而其他模型则使用来自其他数据库的表。

如果您有相同的表,在不同的数据库中是公用的,并且由单个模型共享,则ActiveRecord将无济于事。 早在2009年,我就在一个使用Rails 2.3.8的项目中对此进行了要求。 我有一个针对每个客户的数据库,并用他们的ID命名数据库。 所以我创建了一个方法来更改ApplicationController内部的连接:

def change_database database_id = params[:company_id]
    return if database_id.blank?

    configuration = ActiveRecord::Base.connection.instance_eval { @config }.clone
    configuration[:database] = "database_name_#{database_id}_#{RAILS_ENV}"

    MultipleDatabaseModel.establish_connection configuration
end

并将该方法作为before_filter添加到所有控制器中:

before_filter :change_database

因此,对于每个控制器的每个动作,定义并设置params [:company_id]时,它将把数据库更改为正确的数据库。

为了处理迁移,我扩展了ActiveRecord :: Migration,其方法是查找所有客户并使用每个ID迭代一个块:

class ActiveRecord::Migration
    def self.using_databases *args
        configuration = ActiveRecord::Base.connection.instance_eval { @config }
        former_database = configuration[:database]

        companies = args.blank? ? Company.all : Company.find(args)

        companies.each do |company|
            configuration[:database] = "database_name_#{company[:id]}_#{RAILS_ENV}"
            ActiveRecord::Base.establish_connection configuration

            yield self
        end

        configuration[:database] = former_database
        ActiveRecord::Base.establish_connection configuration
    end
end

请注意,通过这样做,您将不可能在同一操作中从两个不同的数据库中进行查询。 您可以再次调用change_database,但是当您尝试使用从不再链接到正确数据库的对象执行查询的方法时,它将变得很讨厌。 同样,很明显,您将无法联接属于不同数据库的表。

为了正确处理此问题,应将ActiveRecord进行相当大的扩展。 现在应该有一个插件可以帮助您解决此问题。 快速研究给了我这个:

DB-Charmer:[http://kovyrin.github.com/db-charmer/]

我愿意尝试。 让我知道什么对您有用。

adeandrade answered 2020-01-24T02:55:26Z
12 votes

我通过使用其他数据库将其添加到模型顶部来解决了这个问题

class Customer < ActiveRecord::Base
  ENV["RAILS_ENV"] == "development" ? host = 'devhost' : host = 'prodhost'

  self.establish_connection(
      :adapter  => "mysql",
      :host     => "localhost",
      :username => "myuser",
      :password => "mypass",
      :database => "somedatabase"
    )
rdaniels answered 2020-01-24T02:55:45Z
4 votes

您还应该签出一个名为DB Charmer的项目:[http://kovyrin.net/2009/11/03/db-charmer-activerecord-connection-magic-plugin/]

DbCharmer是ActiveRecord的一个简单而功能强大的插件,它可以执行以下操作:

  1. 使您可以轻松管理AR模型的连接(on_*方法)
  2. 允许您将AR模型的默认连接切换到单独的服务器/数据库
  3. 使您可以轻松选择查询的去向(on_*方法系列)
  4. 允许您自动将读取查询发送给从属服务器,而主服务器将处理所有更新。
  5. 将多个数据库迁移添加到ActiveRecord
SquareCog answered 2020-01-24T02:56:32Z
2 votes

值得注意的是,在所有这些解决方案中,您都需要记住关闭自定义数据库连接。 您将用尽连接,否则将看到奇怪的请求超时问题。

一个简单的解决方案是clear_active_connections! 在控制器的after_filter中。

after_filter :close_custom_db_connection

def close_custom_db_connection
  MyModelWithACustomDBConnection.clear_active_connections!
end
Steven Soroka answered 2020-01-24T02:56:57Z
0 votes

在您的config / database.yml中做这样的事情

default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5

development:
  <<: *default
  database: mysite_development

test:
  <<: *default
  database: mysite_test

production:
  <<: *default
  host: 10.0.1.55
  database: mysite_production
  username: postgres_user
  password: <%= ENV['DATABASE_PASSWORD'] %>

db2_development:
  <<: *default
  database: db2_development

db2_test:
  <<: *default
  database: db2_test

db2_production:
  <<: *default
  host: 10.0.1.55
  database: db2_production
  username: postgres_user
  password: <%= ENV['DATABASE_PASSWORD'] %>

那么在您的模型中,您可以使用

class Customers < ActiveRecord::Base
  establish_connection "db2_#{Rails.env}".to_sym
end
rdaniels answered 2020-01-24T02:57:21Z
0 votes

您在问题中描述的是多租户(结构相同的数据库,每个数据库中都有不同的数据)。 Apartment gem非常适合此。

对于Rails中多个数据库的一般问题:ActiveRecord支持多个数据库,但是Rails没有提供管理它们的方法。 我最近创建了Multiverse宝石来解决这个问题。

Andrew Kane answered 2020-01-24T02:57:46Z
0 votes

到目前为止,我发现的最佳解决方案是:

我们可以采用3种数据库架构。

  • 单一数据库的单租户
  • 每个租户的独立架构
  • 租户共享架构

注意:它们的优缺点取决于您的用例。

我是从此Blog获得的! 对我很有帮助。

您可以使用宝石公寓作为护栏

您可以在Gorails上观看有关公寓的视频参考

Dibyajit Goswami answered 2020-01-24T02:58:41Z
translate from https://stackoverflow.com:/questions/1825844/multiple-databases-in-rails