Können Sie DB-Benutzername, pw, Datenbankname in Rails erhalten?

146

Ich schreibe eine Rake-Aufgabe, die einige DB-Arbeiten außerhalb von Rails / ActiveRecord ausführt.

Gibt es eine Möglichkeit, die DB-Verbindungsinformationen (Host, Benutzername, Kennwort, DB-Name) für die aktuelle Umgebung abzurufen, wie in definiert database.yml?

Ich möchte es bekommen, damit ich es so verbinden kann ...

con = Mysql.real_connect("host", "user", "pw", "current_db")
Ethan
quelle

Antworten:

244

Innerhalb von Schienen können Sie ein Konfigurationsobjekt erstellen und die erforderlichen Informationen daraus abrufen:

config   = Rails.configuration.database_configuration
host     = config[Rails.env]["host"]
database = config[Rails.env]["database"]
username = config[Rails.env]["username"]
password = config[Rails.env]["password"]

Weitere Informationen finden Sie in der Dokumentation zu Rails :: Configuration.

Dies verwendet nur YAML :: load , um die Konfiguration aus der Datenbankkonfigurationsdatei ( database.yml) zu laden, mit der Sie die Informationen von außerhalb der Rails-Umgebung abrufen können:

require 'YAML'
info = YAML::load(IO.read("database.yml"))
print info["production"]["host"]
print info["production"]["database"]
...
Robert Gamble
quelle
27
In neueren Rails müssen Sie die Konfiguration nicht erstellen, Sie können sie überRails.configuration
Bryan Larsen
Für Rails 3.0.0 benötigen Sie 'yaml' und YAML :: load (IO.read ("config / database.yml")) funktioniert einwandfrei!
Arivarasan L
Wenn einige davon keine Werte haben (in meinem Fall: Host, Benutzername und Passwort), welche Standardeinstellungen würde Rails verwenden?
Dennis
3
Vorsicht bei der Verwendung von YAML - moderne Versionen von Rails filtern den Dateiinhalt zuerst über ERB.
Kelvin
@BryanLarsen Könnten Sie das näher erläutern? ̶ ̶ ̶R̶a̶i̶l̶s̶.̶c̶o̶n̶f̶i̶g̶u̶r̶a̶t̶i̶o̶n̶̶ Und was dann anders zu sein die Antwort? ̶ Vielleicht war die Antwort von Original bearbeitet. Ich sehe @ KenB Antwort.
Mlt
156

Bryans Antwort im obigen Kommentar verdient etwas mehr Aufmerksamkeit:

>> Rails.configuration.database_configuration[Rails.env]
=> {"encoding"=>"unicode", "username"=>"postgres", "adapter"=>"postgresql", "port"=>5432, "host"=>"localhost", "password"=>"postgres", "database"=>"mydb", "pool"=>5}
KenB
quelle
7
Beim Upgrade auf Rails 4.1 unter Heroku musste ich diese Zeile auf ActiveRecord :: Base.configurations [Rails.env]
umstellen
82
ActiveRecord::Base.connection_config

Gibt die Verbindungskonfiguration in einem Hash zurück:

=> {:adapter=>ADAPTER_NAME, :host=>HOST, :port=>PORT, 
    :database=>DB, :pool=>POOL, :username=>USERNAME, 
    :password=>PASSWORD} 

Wie tpettin ihrem Kommentar bemerkt: Diese Lösung berücksichtigt das Zusammenführen der Konfiguration von database.ymlund zur Umgebungsvariablen DATABASE_URL.

qqbenq
quelle
10
Dies scheint die einzige zu sein, die für das Zusammenführen der database.ymlKonfiguration mit der DATABASE_URLUmgebungsvariablen verantwortlich ist.
Tpett
Ich kann für niemanden sprechen, aber das ist perfekt. Ich wollte programmgesteuert überprüfen, ob ich auf die richtige Datenbank zeigte
jaydel
3

Ich denke, das ist die einfachste Lösung. Nach einigen Tests (mindestens in Rails 5.2) wird DATABASE_URL korrekt aufgelöst.

 ActiveRecord::Base.configurations[Rails.env]
derosm2
quelle
1

Alte Frage, aber dies war eine meiner ersten Stationen, als ich nachschaute, wie das geht, also denke ich, dass dies jemand anderem helfen könnte. Normalerweise habe ich .my.cnf-Dateien im Home-Verzeichnis. Wenn ich also das Juwel 'parseconfig' und eine ERB-Syntax in meiner Konfigurationsdatei database.yml verwende, habe ich eine dynamische Datei, in der ich mich beim Einchecken in die Quellcodeverwaltung wohlfühlen und auch die Bereitstellung vereinfachen kann (in meinem Fall). Beachten Sie auch die Liste der gängigen Sockets. Dadurch wird es einfacher, meine App auf verschiedene Betriebssysteme zu verschieben, die möglicherweise einen anderen Unix-Socket-Pfad haben.

<% 
    require 'parseconfig'
    c=ParseConfig.new('../../.my.cnf') %>

mysqlevn: &mysql
  adapter: mysql 
  username: <%= c.params['client']['user'] %>
  password: <%= c.params['client']['password'] %>
  host: localhost 
  socket: <%= [ 
  '/var/run/mysqld/mysqld.sock',
  '/var/lib/mysql/mysql.sock',
  '/tmp/mysqld.sock',
  '/tmp/mysql.sock'].detect { |socket| File.exist?(socket) } %>

production:
  database: app_production
  <<: *mysql


development:
  database: app_development 
  <<: *mysql

# Do not set this db to the same as development or production.
test:
  database: app_test
  <<: *mysql

Ref: http://effectif.com/articles/database-yml-should-be-checked-in

edwardsharp
quelle