Frage Verbinden von Rails 3.1 mit mehreren Datenbanken


Bei ShowNearby haben wir eine sehr große Migration zu RoR 3.1 von PHP gemacht und wir stehen vor einigen Problemen, die einige von euch schon früher gelöst haben.

Wir haben große Datenmengen und haben uns entschieden, unsere DB in mehrere DBs zu trennen, die wir getrennt verwalten können. Zum Beispiel sind unsere Konten, Orte, Protokolle und andere in mehrere Datenbanken aufgeteilt

Wir müssen Migrationen, Geräte, Modelle, um gut spielen zu können, und bisher war es ziemlich unordentlich. Einige unserer Anforderungen für eine akzeptable Lösung:

  • Ein Modell sollte sich auf eine Tabelle in einer der Datenbanken beziehen.
  • Rake db: drop - sollte alle Datenbank-env löschen, die wir in database.yml angeben
  • Rake db: create - sollte alle Datenbank env erstellen, die wir in database.yml angeben
  • Rake db: migrate - sollte Migrationen zu den verschiedenen Datenbanken ausführen
  • Rake db: test - sollte Geräte greifen und sie in die verschiedenen Datenbanken fallen lassen und Gerät / Funktion / etc testen

Wir denken darüber nach, für jede Datenbank separate Rails-Projekte zu setzen und sie mit ActiveResource zu verbinden, aber wir sind der Meinung, dass dies nicht sehr effizient ist. Hat jemand von euch schon einmal mit einem ähnlichen Problem zu tun?

Vielen Dank!!


76
2018-05-25 09:50


Ursprung


Antworten:


Zur Antwort von Wukerplank können Sie die Verbindungsdetails auch in Datenbank.yml wie üblich mit einem Namen wie folgt setzen:

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

Dann in deinem speziellen Modell:

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

Damit diese lästigen Anmeldeinformationen nicht in Ihrem Anwendungscode enthalten sind.

Bearbeiten: Wenn Sie diese Verbindung in mehreren Modellen wiederverwenden möchten, sollten Sie eine neue abstrakte Klasse erstellen und von ihr erben, da Verbindungen eng mit Klassen verbunden sind (wie erläutert) Hier, Hier, und Hier), und neue Verbindungen werden für jede Klasse erstellt.

Wenn dies der Fall ist, richten Sie die Dinge so ein:

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

141
2018-05-25 15:11



Die Verbindung zu verschiedenen Datenbanken ist ziemlich einfach:

# 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

Ich würde misstrauisch sein, mehrere Rails-Projekte einzurichten, da Sie dem Datenabruf für Ihre Controller viel Aufwand hinzufügen, was die Dinge verlangsamen könnte.

Was Ihre Fragen zu Migrationen, Einbauten, Modellen usw. angeht: Ich glaube nicht, dass es einen einfachen Weg geben wird. Also posten Sie bitte separate Fragen und seien Sie so spezifisch wie möglich.

Konsolidieren der DBs zu einem ist keine Option? Es würde dein Leben viel einfacher machen!


18
2018-05-25 10:06



Ich habe einen tollen Beitrag gefunden, der andere auf den richtigen Weg zum Checkout bringen wird http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-ruby.html

Richte es so ein:

database.yml (Konfigurationsdatei der Datenbank)

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

support_base.rb (eine Modelldatei)

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

tst_test.rb (eine Modelldatei)

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, dies deckt Migrationen wirklich nicht ab, ich glaube nicht, dass Sie Migrationen in mehr als einer Datenbank mit Rake durchführen können (obwohl ich mir nicht sicher bin, ob das ein hartes "nicht möglich" ist, könnte es möglich sein). Dies war nur eine gute Möglichkeit, andere DBs, die Sie nicht kontrollieren, zu verbinden und abzufragen.


11
2017-07-13 23:59



Möglicherweise möchten Sie auch die Rails-Umgebung anhängen, sodass Ihre Entwicklungs- und Testdatenbanken nicht identisch sind.

establish_connection "legacy_#{Rails.env}"

4
2018-05-16 13:18



Das folgender Artikel schlägt vor, neue Rake-Aufgaben zu definieren, um Migrationen gegen mehrere Datenbanken zu erreichen. Jede Task baut ihre eigene Verbindung auf und führt dann die Migration mit dieser Verbindung und dem spezifischen Datenbankordner aus.

Es definiert auch ein Vertrautes db:migrate das ruft die zwei anderen Aufgaben auf.

Einschließen hier, wenn der Link nicht mehr verfügbar ist:

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

Quelle:  Ruby on Rails verbindet sich mit mehreren Datenbanken und Migrationen


3
2018-06-17 14:30



Hey, dieser Beitrag ist alt, aber ich habe eine Lösung gefunden, die auf Rails 3.2 funktioniert und jemand anderem helfen könnte. https://Stackoverflow.com/a/16542724/1447654


1
2018-05-14 13:35