【问题标题】:Correctly configuring a Postgres DB for a Rails 4.2 app on Heroku在 Heroku 上为 Rails 4.2 应用程序正确配置 Postgres DB
【发布时间】:2015-04-14 23:36:41
【问题描述】:

我对如何在使用 Postgres 和 Heroku 的 Rails 4.2 应用程序中配置数据库感到困惑。

按照in this Heroku guide 的建议,你会得到一个像这样的config/database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  timeout: 5000

development:
  <<: *default
  database: app_name_development

test:
  <<: *default
  database: app_name_test

production:
  <<: *default
  database: app_name_production

但是当我尝试这个时,我的开发和测试环境使用与登台环境相同的数据库(注意该文件没有登台配置)。这不好。

Heroku guide for connecting to the DB in Ruby 提到任何 Rails 应用程序在 4.2 之前的database.yml 文件都会被 Heroku 覆盖。 Heroku 将解析DATABASE_URL 环境变量并创建一个新的database.yml 文件。

所以我想对于您在 Heroku 上的任何环境(例如登台和生产),可以省略 database.yml 中的配置。您的 database.yml file could essentially look like Hound's(请注意缺少生产配置)。

development: &default
  adapter: postgresql
  encoding: unicode
  database: app_development
  pool: 5

test:
  <<: *default
  database: app_test

但由于我们使用的是 Rails 4.2,我认为 Heroku 不会覆盖 database.yml 文件。在这种情况下,您是否必须在database.yml 中为我们在 Heroku 上的环境指定数据库配置?或者将它们排除在外仍然安全吗?如果我们确实需要为 Heroku 环境指定配置,那么以下就足够了吗?

staging:
  url: <%= ENV['DATABASE_URL'] %>

production:
  url: <%= ENV['DATABASE_URL'] %>

我也对开发和测试环境的正确配置感到困惑。正如我上面提到的,显示的第一个配置具有使用 Heroku 上的暂存数据库而不是本地数据库的环境。

This Heroku guide 表示要导出DATABASE_URL 环境变量以供您的应用连接(一旦安装了 Postgres,您就可以连接到它)。

假设您按照文章中的说明导出DATABASE_URL env var,那么您的开发和测试配置应该是什么样的?我们是否按照第一个指南中所示的配置进行配置,例如

default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  timeout: 5000

development:
  <<: *default
  database: app_name_development

test:
  <<: *default
  database: app_name_test

或者我们是否使用this Heroku guide 中所示的配置(使用hostusername

development:
  adapter: postgresql
  host: localhost
  username: user
  database: app-dev

更新 1:这是我现在知道的。如果您部署到 Heroku,无论您的 Rails 版本如何,config/database.yml 都不需要暂存和生产配置。在 4.2 之前,Heroku 会根据 DATABASE_URL 环境变量的值生成它自己的 database.yml 文件,覆盖你的配置文件(如果它存在的话)。从 Rails 4.2 开始,您的应用将直接使用 DATABASE_URL 环境变量(绕过 database.yml 文件),因此 Heroku 不需要(也不会)生成配置文件。

我还弄清楚了为什么我的开发和测试环境使用 Heroku 应用程序中的远程暂存数据库,而不是在其 database.yml 配置中指定的本地数据库。这是因为我用于开发的本地.env 文件基于我的暂存.env 文件,该文件包含用于连接到数据库的环境变量,例如DATABASE_URL。因为DATABASE_URL 存在于我的开发.env 文件中,所以我的Rails 4.2 应用程序正在使用它并因此连接到暂存数据库。为了修复它,我从开发 .env 文件中删除了这些环境变量,并使用 bundle exec rake db:setup 创建了本地 DB(并运行了迁移)。

更新 2: Rails 指南的这一部分更详细地介绍了如何配置数据库,值得一读:http://guides.rubyonrails.org/configuring.html#configuring-a-database

【问题讨论】:

    标签: ruby-on-rails postgresql heroku ruby-on-rails-4.2


    【解决方案1】:

    您的大多数假设都是正确的。以下是合理的database.yml配置文件。

    default: &default
      adapter: postgresql
      encoding: unicode
      pool: 5
      timeout: 5000
    
    development:
      <<: *default
      database: app_name_development
    
    test:
      <<: *default
      database: app_name_test
    
    staging:
      url: <%= ENV['DATABASE_URL'] %>
    
    production:
      url: <%= ENV['DATABASE_URL'] %>
    

    确保在 Heroku 上正确设置了 RAILS_ENVstagingproduction),否则 Rails 将默认为 development

    在本地,测试将选择test 环境。默认情况下,应用程序将以开发模式启动,使用 development 环境。

    【讨论】:

    • Simone,目前放置'pool: ' 到生产选项?我的 database.yml 目前是 gitignored,但对于线程服务器,heroku 建议将池值设置为与 database.yml 文件中的 MAX_THREADS 相同。我问这个问题是为了确保我不会做任何愚蠢的事情,因为当涉及到 database.yml 时,heroku 的文档措辞听起来很矛盾。
    【解决方案2】:

    事实上,许多开发人员选择忽略版本控制中的database.yml,并且从不将其发布到存储库中。原因是,不同机器上的数据库可能不同,这就是不保持配置通用的原因。

    我现在正在开发一个 Rails 4.2 项目,Heroku 完全没有database.yml 的问题(对于 PostgreSQL 和 MySQL,我们都进行了测试)。为什么?因为DATABASE_URL 提供了访问数据库所需的所有信息,甚至适配器名称。如何?这是公式:

    adapter://username:password@hostname:port/database?options
    

    在本地,我使用带有对等身份验证的 Postgres:数据库服务器假定我在我的操作系统中使用的用户名相同,username 被覆盖,password 无用。当没有给出host 时,假定本地机器,虽然我不知道它是否尝试通过 TCP/IP 或 Unix 域套接字进行通信,所以没有host 我很好。

    因此,您所说的“在第一个指南中显示”的配置是合理的:它包含最少的设置,并且允许您轻松创建更多环境。

    【讨论】:

    【解决方案3】:

    Heroku 不会在 rails 4.2 上创建 database.yml,因为从该版本开始,rails 将检测该环境变量的存在并使用它来配置数据库连接。

    添加

    production:
      url: <%= ENV['DATABASE_URL'] %>
    

    让那些可能不知道但不会改变行为的人更清楚正在发生的事情。如果您需要,configuring rails 指南提供了有关 database.yml 和 DATABASE_URL 之间交互的更多信息。

    【讨论】:

      【解决方案4】:

      要在没有 Rails 的情况下连接 ActiveRecord(例如 sinatra):

      url = URI.parse(ENV['DATABASE_URL'])
      ActiveRecord::Base.establish_connection(
        encoding: 'unicode',
        pool: 5,
        timeout: 5000,
        reconnect: true,
        adapter: url.scheme,
        host: url.host,
        database: url.path.sub(%r{^/}, ''),
        username: url.user,
        password: url.password
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-12
        • 2011-12-17
        • 1970-01-01
        • 2013-11-26
        • 1970-01-01
        相关资源
        最近更新 更多