Ruby-on-rails 将 Rails 3.1 与多个数据库连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6122508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 01:14:28  来源:igfitidea点击:

Connecting Rails 3.1 with Multiple Databases

ruby-on-railsrubyruby-on-rails-3rails-activerecordactiveresource

提问by Fer Martin

At ShowNearby we have been doing a very big migration to RoR 3.1 from PHP and we are facing several problems that may be some of you have solved before.

在 ShowNearby,我们一直在进行从 PHP 到 RoR 3.1 的大规模迁移,我们面临着一些问题,你们中的一些人可能已经解决了这些问题。

We have big amounts of data and we decided to segregate our DB into several DBs that we can handle separately. For example, our accounts, places, logs and others are split into several databases

我们有大量数据,我们决定将我们的数据库分成几个我们可以单独处理的数据库。比如我们的账号、地点、日志等被拆分成几个数据库

We need to get migrations, fixtures, models, to play nicely, and so far it has been quite messy. Some of our requirements for a solution to be acceptable:

我们需要得到迁移、装置、模型,才能很好地发挥作用,到目前为止,它已经相当混乱了。我们对可接受的解决方案的一些要求:

  • one model should relate to one tables in one of the databases.
  • rake db:drop - should drop all the database env we specify in database.yml
  • rake db:create - should create all the database env we specify in database.yml
  • rake db:migrate - should run migrations to the various databases
  • rake db:test - should grab fixtures and drop them into the various databases and test unit/function/etc
  • 一种模型应与其中一个数据库中的一张表相关。
  • rake db:drop - 应该删除我们在 database.yml 中指定的所有数据库环境
  • rake db:create - 应该创建我们在 database.yml 中指定的所有数据库环境
  • rake db:migrate - 应该运行到各种数据库的迁移
  • rake db:test - 应该抓取夹具并将它们放入各种数据库和测试单元/功能/等

We are considering setting separate rails projects per each database and connecting them with ActiveResource, but we feel this is not very efficient. Have any of you deal with a similar problem before?

我们正在考虑为每个数据库设置单独的 rails 项目并将它们与 ActiveResource 连接,但我们觉得这不是很有效。你们中有人以前处理过类似的问题吗?

回答by Unixmonkey

To Wukerplank's answer, you can also put the connection details in database.yml like usual with a name like so:

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

log_database_production:
  adapter: mysql
  host: other_host
  username: logmein
  password: supersecret
  database: logs

Then in your special model:

然后在您的特殊模型中:

class AccessLog < ActiveRecord::Base
  establish_connection "log_database_#{Rails.env}".to_sym
end

To keep those pesky credentials from being in your application code.

防止那些讨厌的凭据出现在您的应用程序代码中。

Edit:If you want to reuse this connection in multiple models, you should create a new abstract class and inherit from it, because connections are tightly coupled to classes (as explained here, here, and here), and new connections will be created for each class.

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

If that is the case, set things up like so:

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

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

回答by Wukerplank

Connecting to different databases is quite easy:

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

# 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

I would be wary of setting up multiple Rails projects as you will add a lot of overhead to data retrieval for your controllers, which could make things slow.

我会警惕设置多个 Rails 项目,因为您会为控制器的数据检索增加大量开销,这可能会使事情变慢。

As for your questions about migrations, fixtures, models etc.: I don't think there will be an easy way, so please post separate questions and be as specific as you can.

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

Consolidating the DBs into one is not an option? It would make your life a lot easier!

将数据库合并为一个不是一种选择吗?它会让你的生活轻松很多!

回答by TwoByteHero

Found a great post that will point others to the right way of doing this check out http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-ruby.html

找到了一篇很棒的文章,可以为其他人指出正确的方法,请查看 http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-ruby.html

Set it up something like this:

设置它是这样的:

database.yml (db config file)

database.yml(数据库配置文件)

support_development:
    adapter: blah
    database: blah
    username: blah
    password: blah

support_base.rb (a model file)

support_base.rb(模型文件)

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

tst_test.rb (a model file)

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

PS, this really doesn't cover migrations, I don't think you can do migrations on more than one DB with rake (although I'm not sure that is a hard 'cannot do', it may be possible). This was just a great way to connect and query other DBs that you don't control.

PS,这真的不包括迁移,我认为您不能使用 rake 在多个数据库上进行迁移(尽管我不确定这是一个很难的“不能做”的事情,但它可能是可能的)。这只是连接和查询您无法控制的其他数据库的好方法。

回答by Kris

You might also want to append the Rails environment, so your development and test databases are not the same.

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

establish_connection "legacy_#{Rails.env}"

回答by cweston

The following articlesuggests defining new Rake tasks to achieve migrations against multiple databases. Each task sets up its own connection and then executes the migration with this connection and the specific database folder.

下面的文章指出定义新的Rake任务,以实现对多个数据库迁移。每个任务都会建立自己的连接,然后使用此连接和特定的数据库文件夹执行迁移。

It also defines a familiar db:migratethat calls the two other tasks.

它还定义了一个熟悉的db:migrate调用其他两个任务。

Including here incase the link becomes unavailable:

包括此处以防链接变得不可用:

desc "Migrate the database through scripts in db/migrate directory."

namespace :db do
  task :migrate do
    Rake::Task["db:migrate_db1"].invoke
    Rake::Task["db:migrate_db2"].invoke
  end

  task :migrate_db1 do
    ActiveRecord::Base.establish_connection DB1_CONF
    ActiveRecord::Migrator.migrate("db/migrate/db1/")
  end

  task :migrate_db2 do
    ActiveRecord::Base.establish_connection DB2_CONF
    ActiveRecord::Migrator.migrate("db/migrate/db2/")
  end
end

Source:Ruby on Rails Connect to Multiple Databases and Migrations

来源:Ruby on Rails 连接到多个数据库和迁移

回答by Rafael

Hey this post is old but I've found a solution working on Rails 3.2 that might help someone else. https://stackoverflow.com/a/16542724/1447654

嘿,这篇文章很旧,但我找到了一个适用于 Rails 3.2 的解决方案,可能会帮助其他人。 https://stackoverflow.com/a/16542724/1447654