77

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

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

うまくプレイするには、移行、フィクスチャ、モデルを取得する必要がありますが、これまでのところ、かなり面倒です。ソリューションが受け入れられるための要件の一部:

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

データベースごとに別々の Rails プロジェクトを設定し、ActiveResource で接続することも検討していますが、あまり効率的ではないと感じています。以前に同様の問題に対処した人はいますか?

4

6 に答える 6

142

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

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

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

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

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
于 2011-05-25T15:11:52.753 に答える
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

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

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

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

于 2011-05-25T10:06:06.003 に答える
11

http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-ruby.htmlをチェックして、これを行う正しい方法を他の人に指摘する素晴らしい投稿を見つけました

次のように設定します。

database.yml (データベース構成ファイル)

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

于 2012-07-13T23:59:20.183 に答える
5

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

establish_connection "legacy_#{Rails.env}"
于 2012-05-16T13:18:50.447 に答える
3

次の記事では、新しい 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 複数のデータベースと移行に接続

于 2015-06-17T14:30:45.157 に答える
1

この投稿は古いですが、Rails 3.2 で動作する解決策を見つけたので、他の人に役立つかもしれません。 https://stackoverflow.com/a/16542724/1447654

于 2013-05-14T13:35:35.040 に答える