覆盖database.yml的策略?

发布于 2024-10-02 18:08:06 字数 1204 浏览 8 评论 0原文

在我的环境中,部署服务器拥有 database.yml 中的许多连接信息。也就是说,它们知道自己是开发、测试还是生产服务器,并且知道各自的数据库连接信息。

例如,我可以将此信息封装在 Server 类中,以便我可以检索信息:

Server["environment"] #=> production
Server["db_host"] #=> db5.example.com
Server["db_password"] #=> [a decrypted password]

等等。我想部署一个 Rails 应用程序并根据服务器设置自动配置它。最好的方法是什么?

一种方法是在我的database.yml中添加Erb:

<%= Server["environment"] %>: 
  adapter: oracle_enhanced
  host: <%= Server["db_host"] %>
  username: db_user 
  password: <%= Server["password"] %>

我对这种方式不太感兴趣,但它会起作用。在这种情况下,我应该把定义 Server 类的“server.rb”放在哪里——在 yml 中需要它? ActiveRecord 加载database.yml 之后加载app/initializers。

另一种可能的解决方案是以某种方式覆盖 Railties 的数据库初始值设定项:

# File railties/lib/initializer.rb, line 903
def database_configuration
  require 'erb'
  YAML::load(ERB.new(IO.read(database_configuration_file)).result)
end

仅当 :active_record 在 config.frameworks 中定义时才会调用上述内容。我不确定如何在 Rails 启动序列中尽早覆盖这一点。

也许第三个选项是从 config.frameworks 中删除 :active_record,然后稍后创建连接,比如在应用程序初始化程序中?恐怕这可能会产生很多意想不到的副作用。

希望有一些我还没有发现的简单而明显的东西,例如允许我选择退出database.yml并以编程方式提供备用配置的ActiveRecord功能。

In my environment, the deployment servers have much of the connection information that is in the database.yml. That is, they know whether they are development, test or production servers, and they know their respective database connection information.

I can encapsulate this information in a Server class for example, so that I can retrieve the information:

Server["environment"] #=> production
Server["db_host"] #=> db5.example.com
Server["db_password"] #=> [a decrypted password]

and so on. I would like to deploy a Rails application and have it autoconfigure based on the Server settings. What is the best way to do this?

One way to do this is Erb in my database.yml:

<%= Server["environment"] %>: 
  adapter: oracle_enhanced
  host: <%= Server["db_host"] %>
  username: db_user 
  password: <%= Server["password"] %>

I'm not too thrilled about doing it this way, but it would work. In this case, where would I put the 'server.rb' that defines the Server class--require it here in the yml? app/initializers gets loaded after ActiveRecord loads database.yml.

Another possible solution is to somehow override railties' database initializer:

# File railties/lib/initializer.rb, line 903
def database_configuration
  require 'erb'
  YAML::load(ERB.new(IO.read(database_configuration_file)).result)
end

The above is called only if :active_record is defined in config.frameworks. I'm not sure how I would go about overriding this early enough in the Rails startup sequence.

Maybe a third option is to remove :active_record from config.frameworks, and then create the connection later, say in the app initializers? I'm afraid this may have lots of unintended side effects.

I'm hoping that there's something simple and obvious that I haven't found, such as an ActiveRecord feature that allows me to opt out of database.yml and provide alternate config programmatically.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

已下线请稍等 2024-10-09 18:08:06

您可以直接在 application.rb 中提供您自己的数据库自定义:
Rails 3.2 似乎工作得很好。 (但请注意,这是一种猴子修补)

module MyApp 
  class Application < Rails::Application
    # ... config 
    config.encoding = "utf-8" 

    def config.database_configuration
      parsed = super
      raise parsed.to_yaml  # Replace this line to add custom connections to the hash from database.yml
    end
  end
end

You can provide your own database customizations directly in your application.rb:
It seems to work nice rails 3.2. (Be warned though, it's a kind-of monkey patching)

module MyApp 
  class Application < Rails::Application
    # ... config 
    config.encoding = "utf-8" 

    def config.database_configuration
      parsed = super
      raise parsed.to_yaml  # Replace this line to add custom connections to the hash from database.yml
    end
  end
end
望她远 2024-10-09 18:08:06

这似乎适用于 Rails 3.2.2

module MyApp 
  class Application < Rails::Application
    self.paths['config/database'] = 'config/another_db.yml'
  end
end

This seems to work in Rails 3.2.2

module MyApp 
  class Application < Rails::Application
    self.paths['config/database'] = 'config/another_db.yml'
  end
end
洛阳烟雨空心柳 2024-10-09 18:08:06

这是一个老问题,但在 Rails 4 中,您可以简单地使用环境变量并拥有空白或缺失的database.yml(DATABASE_URL将覆盖任何database.yml)

DATABASE_URL=postgres:/ /myuser:[电子邮件受保护]:5432/my-database-name< /code>

更多信息:http://edgeguides.rubyonrails.org/configuring.html#connection-preference

This is an old question, but in Rails 4 you can simply use an environment variable and have a blank or missing database.yml (DATABASE_URL will override any database.yml)

DATABASE_URL=postgres://myuser:[email protected]:5432/my-database-name

more here: http://edgeguides.rubyonrails.org/configuring.html#connection-preference

时光清浅 2024-10-09 18:08:06

有两个技巧可能会有所帮助。其中之一是您所触及的,即对数据库配置中加载的例程进行猴子修补,这当然是值得探索的事情。 Ruby 的好处是您几乎可以修补任何您不喜欢的内容并用更好的内容替换它。这里的责任是,较新版本的 Rails 可能会使用不同的配置机制,并且您的补丁将导致一切损坏。也许这是值得付出的代价。

另一种方法是将database.yml 文件保存在服务器上而不是存储库中,并使用某种部署脚本将其链接到适当的位置。这种方法的优点是您的版本控制系统中没有重要的密码,并且您可以更新服务器的配置而无需修补应用程序。

There's two tricks which might help here. One is what you've touched on, that being monkey-patching the routine that loads in the database configuration, and that's certainly something worth exploring. The nice thing about Ruby is you can pretty much patch out anything you don't like and replace it with something better. The liability here is that a newer version of Rails might use a different mechanism for configuration and your patch will cause everything to break. Maybe that's a price worth paying.

The other approach is to keep the database.yml file on the server instead of in your repository, and have some kind of deployment script that links it in to the appropriate location. The advantage to this approach is you don't have important passwords floating around in your version control system and you can update a server's configuration without having to patch the application.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文