it-swarm.com.de

Mehrere Datenbanken in Rails

Kann das gemacht werden? In einer einzigen Anwendung, die viele Projekte mit SQLite verwaltet. Was ich möchte, ist, dass für jedes Projekt, das meine App verwaltet, eine andere Datenbank vorhanden ist. Mehrere Kopien einer identisch strukturierten Datenbank, jedoch mit unterschiedlichen Daten. Ich wähle aus, welche Kopie auf Basis der Parameter für die URI verwendet werden soll.

Dies geschieht für 1. Sicherheit. Ich bin ein Neuling in dieser Art der Programmierung und ich möchte nicht, dass aus irgendeinem Grund während der Arbeit an einem Projekt ein anderer beschädigt wird. 2. Einfache Sicherung und Archivierung von alte Projekte

50
luca

Rails ist standardmäßig nicht für eine Multi-Datenbank-Architektur ausgelegt und in den meisten Fällen macht es überhaupt keinen Sinn .. __ Ja, Sie können verschiedene Datenbanken und Verbindungen verwenden.

Hier einige Referenzen:

39
Simone Carletti

Wenn Sie jede Rails-Instanz steuern und konfigurieren können und Ressourcen verschwenden können, weil sich diese im Standby-Modus befinden, sparen Sie sich einige Probleme und ändern Sie einfach die Datei database.yml, um die in jeder Instanz verwendete Datenbankverbindung zu ändern. Wenn Sie über die Leistung besorgt sind, wird dieser Ansatz das nicht beeinträchtigen.

Für Modelle, die an eine einzige eindeutige Tabelle in nur einer Datenbank gebunden sind, können Sie "deploy_connection" innerhalb des Modells aufrufen:

establish_connection "database_name_#{Rails_ENV}"

Wie hier beschrieben: http://apidock.com/Rails/ActiveRecord/Base/establish_connection/class

Sie haben einige Modelle mit Tabellen aus einer Datenbank und andere Modelle mit Tabellen aus anderen Datenbanken.

Wenn Sie identische Tabellen haben, die in verschiedenen Datenbanken vorhanden sind und von einem einzigen Modell gemeinsam genutzt werden, hilft ActiveRecord nicht. 2009 habe ich dies für ein Projekt benötigt, an dem ich mit Rails 2.3.8 gearbeitet habe. Ich hatte eine Datenbank für jeden Kunden und benannte die Datenbanken mit ihren IDs. Also habe ich eine Methode erstellt, um die Verbindung in ApplicationController zu ändern:

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

Und fügte diese Methode als before_filter zu allen Controllern hinzu:

before_filter :change_database

Wenn also für jede Aktion jedes Controllers Parameter [: company_id] definiert und festgelegt sind, ändert sich die Datenbank in die richtige.

Um Migrationen abzuwickeln, erweiterte ich ActiveRecord :: Migration um eine Methode, die nach allen Kunden sucht und mit jeder ID einen Block durchläuft:

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

Beachten Sie, dass Sie auf diese Weise keine Abfragen innerhalb derselben Aktion von zwei verschiedenen Datenbanken durchführen können. Sie können change_database erneut aufrufen, aber es wird unangenehm, wenn Sie versuchen, Methoden zu verwenden, die Abfragen ausführen, und zwar aus Objekten, die nicht mehr mit der richtigen Datenbank verknüpft sind. Es ist auch offensichtlich, dass Sie keine Tabellen verknüpfen können, die zu verschiedenen Datenbanken gehören.

Um dies richtig zu handhaben, sollte ActiveRecord erheblich erweitert werden. Es sollte jetzt ein Plugin geben, um Ihnen bei diesem Problem zu helfen. Eine kurze Recherche ergab mir folgende:

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

Ich bin bereit, es zu versuchen. Lass mich wissen, was für dich funktioniert.

26
adeandrade

Ich bin daran vorbei gekommen, indem ich es oben in meinen Modellen mithilfe der anderen Datenbank hinzugefügt habe

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"
    )
12
rdaniels

Sie sollten sich auch dieses Projekt namens DB Charmer ansehen: http://kovyrin.net/2009/11/03/db-charmer-activerecord-connection-magic-plugin/

DbCharmer ist ein einfaches, aber leistungsfähiges Plugin für ActiveRecord, das einige Dinge bewirkt:

  1. Ermöglicht die einfache Verwaltung von Verbindungen von AR-Modellen (switch_connection_to-Methode) 
  2. Ermöglicht das Wechseln der Standardverbindungen von AR-Modellen zu separaten Servern/Datenbanken
  3. Ermöglicht die einfache Auswahl des Ziels für die Abfrage (on_*-Methodenfamilie)
  4. Ermöglicht das automatische Senden von Leseabfragen an Ihre Slaves, während Master alle Aktualisierungen durchführen.
  5. Fügt mehrere Datenbanken zu ActiveRecord hinzu 
4
SquareCog

Es ist erwähnenswert, dass bei all diesen Lösungen die benutzerdefinierten Datenbankverbindungen geschlossen werden müssen. Ihnen werden die Verbindungen ausgehen und ansonsten treten seltsame Probleme beim Anforderungs-Timeout auf.

Eine einfache Lösung ist das Löschen von aktiven Verbindungen! in einem after_filter in Ihrem Controller.

after_filter :close_custom_db_connection

def close_custom_db_connection
  MyModelWithACustomDBConnection.clear_active_connections!
end
2
Steven Soroka

Die beste Lösung, die ich bisher gefunden habe, ist diese:

Es gibt 3 Datenbankarchitekturen, denen wir uns nähern können.

  • Einzelne Datenbank für einen einzelnen Mandanten
  • Separates Schema für jeden Mandanten
  • Freigegebenes Schema für Mandanten

Hinweis: Sie haben bestimmte Vor- und Nachteile, die von Ihrem Anwendungsfall abhängen.

Ich habe das von diesem Blog ! Steht für mich sehr hilfreich.

Sie können das Juwel Apartment für Rails verwenden

Videoreferenz, die Sie unter Gorails for apartment folgen können

0

Was Sie in der Frage beschrieben haben, ist Multitenancy (identisch strukturierte Datenbanken mit jeweils unterschiedlichen Daten). Das Apartment Juwel ist dafür großartig.

Für die allgemeine Frage nach mehreren Datenbanken in Rails: ActiveRecord unterstützt mehrere Datenbanken, aber Rails bietet keine Möglichkeit, diese zu verwalten. Ich habe vor kurzem das Multiverse gem erstellt, um dieses Problem anzugehen.

0
Andrew Kane

in deiner config/database.yml mache so etwas

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'] %>

dann können Sie in Ihren Modellen auf db2 verweisen

class Customers < ActiveRecord::Base
  establish_connection "db2_#{Rails.env}".to_sym
end
0
rdaniels