web-dev-qa-db-ja.com

複数のデータベースでのRails 3.1の接続

ShowNearbyでは、PHPからRoR 3.1への非常に大きな移行を行っており、これまでに解決したことがあるいくつかの問題に直面しています。

大量のデータがあり、DBを個別に処理できる複数のDBに分離することにしました。たとえば、アカウント、場所、ログなどはいくつかのデータベースに分割されます

マイグレーション、フィクスチャ、モデルを手に入れる必要がありますが、これまでのところ非常に面倒です。ソリューションが受け入れられるための要件の一部:

  • 1つのモデルは、いずれかのデータベース内の1つのテーブルに関連付ける必要があります。
  • rake db:drop-database.ymlで指定したすべてのデータベースenvを削除する必要があります
  • rake db:create-database.ymlで指定したすべてのデータベースenvを作成する必要があります
  • rake db:migrate-さまざまなデータベースへの移行を実行する必要があります
  • rake db:test-フィクスチャを取得し、それらをさまざまなデータベースにドロップして、ユニット/関数/などをテストします。

各データベースごとに別々のRailsプロジェクトを設定し、それらをActiveResourceに接続することを検討していますが、これはあまり効率的ではないと感じています。

本当にありがとう!!

77
Fer Martin

Wukerplankの答えに、接続の詳細を通常のようにdatabase.ymlに入れて、次のような名前にすることもできます。

log_database_production:
  adapter: mysql
  Host: other_Host
  username: logmein
  password: supersecret
  database: logs

次に、特別なモデルで:

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

これらの厄介な資格情報がアプリケーションコードに含まれないようにするため。

Edit:この接続を複数のモデルで再利用したい場合は、新しい抽象クラスを作成して継承する必要があります。 (説明どおり herehere 、および here )、クラスごとに新しい接続が作成されます。

その場合は、次のように設定します。

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
142
Unixmonkey

異なるデータベースへの接続は非常に簡単です。

# 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

複数のRailsプロジェクトを設定するのは慎重になります。コントローラーのデータ取得に多くのオーバーヘッドが追加され、処理が遅くなる可能性があるためです。

移行、フィクスチャ、モデルなどに関する質問については、簡単な方法があるとは思わないので、個別の質問を投稿して、できるだけ具体的にしてください。

DBを1つに統合するオプションはありませんか?それはあなたの人生をずっと楽にしてくれるでしょう!

18
Wukerplank

このチェックアウトを行う正しい方法を他の人に示す素晴らしい投稿を見つけました http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-Ruby.html =

次のように設定します。

database.yml(db configファイル)

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

support_base.rb(モデルファイル)

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

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、これは移行を実際にはカバーしていません。複数のDBでrakeを使用して移行できるとは思いません(それが難しい「できない」ことは確かではありませんが、可能かもしれません)。これは、管理していない他のDBに接続して照会するための優れた方法でした。

11
TwoByteHero

また、Rails環境を追加することもできます。そのため、開発データベースとテストデータベースは同じではありません。

establish_connection "legacy_#{Rails.env}"
5
Kris

次の記事 は、複数のデータベースに対する移行を実現するために新しいRakeタスクを定義することを提案しています。各タスクは独自の接続を設定し、この接続と特定のデータベースフォルダーを使用して移行を実行します。

また、おなじみのdb:migrate他の2つのタスクを呼び出します。

リンクが利用できなくなった場合に備えて、ここに含める:

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

出典:Ruby on Rails複数のデータベースと移行に接続

3
cweston

ちょっとこの投稿は古いですが、Rails 3.2が他の誰かを助けるかもしれない解決策を見つけました。 https://stackoverflow.com/a/16542724/1447654 =

1
Rafael