in Rails, wie führe ich direkten SQL-Code auf einer andere Datenbank?
-
09-06-2019 - |
Frage
Hier ist der Fall.
Ich schreibe eine Rails-Anwendung, die Datenqualität über einige spezifische Datenbanken überwachen. Um das zu tun, muss ich der Lage sein, direkte SQL-Abfragen über diese Datenbanken auszuführen - die natürlich nicht die gleiche wie die verwendet, um die Rails-Anwendung Modelle zu fahren. Kurz gesagt bedeutet dies, ich nicht den Trick, gehen durch die Activebasisverbindung nutzen können.
Die Datenbanken I verbinden müssen, werden zur Entwurfszeit nicht bekannt ist (d.h .: Ich kann nicht ihre Details in database.yaml setzen). Vielmehr habe ich ein Modell ‚database_details‘, die der Benutzer die Details der Datenbanken verwenden geben, über das die Anwendung Abfragen zur Laufzeit ausgeführt wird.
So ist die Verbindung zu diesen Datenbanken wirklich dynamisch ist und die Details werden zur Laufzeit nur gelöst werden.
Wie kann ich das tun?
Danke,
Rollo
Lösung
hatte ich eine Situation wie diese, wo ich Hunderte von verschiedenen Instanzen von einer externen Anwendung hatte zu verbinden, und ich habe Code ähnlich den folgenden:
def get_custom_connection(identifier, host, port, dbname, dbuser, password)
eval("Custom_#{identifier} = Class::new(ActiveRecord::Base)")
eval("Custom_#{identifier}.establish_connection(:adapter=>'mysql', :host=>'#{host}', :port=>#{port}, :database=>'#{dbname}', " +
":username=>'#{dbuser}', :password=>'#{password}')")
return eval("Custom_#{identifier}.connection")
end
Dies hat den zusätzlichen Vorteil, nicht Ihre Active Ändern :: Base-Verbindung, die Ihre Modelle erben von, so dass Sie SQL gegen diese Verbindung und verwerfen das Objekt ausgeführt werden können, wenn Sie mit ihm fertig sind.
Andere Tipps
Sie können programmatisch etablieren Verbindung einen Anruf wie dies mit
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "myuser",
:password => "mypass",
:database => "somedatabase"
)
Wie Sie sehen Sie die somedatabase durch einen database_model.database_name Wert ersetzen kann. gleiche mit dem adatpter und alle
Active :: Base.establish_connection Dokumentation
Dann können Sie
ActiveRecord::Base.find_by_sql("select * ")
Ihre SQL-Abfrage auszuführen.
Active :: Base.find_by_sql Dokumentation
Herr Matt war richtig, wenn unvollständig
Weitere Informationen (veraltet, aber für den Design-Ansatz nach wie vor sinnvoll) können hier und auf die normale Datenbank wiederherzustellen, erinnern, wenn Sie fertig sind:)
Unter Umständen können Sie dies durch tun? self.establish_connection