将Sinatra应用迁移至Heroku PostgreSQL数据库时遇连接错误求助
解决方案:Sinatra + Heroku PostgreSQL 连接失败问题
问题根源分析
你遇到的PG::ConnectionBad错误,本质是应用在生产环境下没有正确读取Heroku注入的DATABASE_URL环境变量, fallback到了代码里的默认值postgres://localhost/production,所以才会尝试连接本地127.0.0.1的PostgreSQL服务。
核心问题有两个:
database.yml的生产环境配置干扰了ActiveRecord的连接逻辑- 环境配置代码存在冗余和潜在的加载顺序问题
具体修复步骤
1. 修正database.yml配置
Heroku会自动为PostgreSQL数据库生成并注入DATABASE_URL环境变量,不需要手动在database.yml里写死生产环境的连接参数——反而会覆盖代码里的配置。修改你的database.yml为:
development: adapter: sqlite3 database: db/development.sqlite pool: 5 production: url: <%= ENV['DATABASE_URL'] %>
或者直接删除production块,让ActiveRecord完全依赖代码里的连接配置。
2. 清理环境配置代码
你的代码里重复执行了bundler/setup和Bundler.require,而且生产环境的URI解析可以简化,修改后的环境文件代码如下:
require 'bundler/setup' Bundler.require configure :development do ENV['SINATRA_ENV'] ||= "development" ActiveRecord::Base.establish_connection( adapter: "sqlite3", database: "db/#{ENV['SINATRA_ENV']}.sqlite" ) end configure :production do # 直接使用Heroku注入的DATABASE_URL,无需手动解析URI ActiveRecord::Base.establish_connection(ENV['DATABASE_URL']) end require_all 'app'
- 删掉了开发环境里重复的
require 'bundler/setup'和Bundler.require,避免加载冲突 - 生产环境直接传入
ENV['DATABASE_URL']给establish_connection,ActiveRecord会自动解析这个URL字符串,无需手动拆分host、username等参数
3. 验证Heroku环境变量
部署后,登录Heroku CLI执行以下命令,确认DATABASE_URL已正确设置:
heroku config:get DATABASE_URL --app your-app-name
如果返回正确的PostgreSQL连接URL(包含Heroku的数据库主机地址,不是localhost),说明环境变量正常。
4. 重新部署
提交修改后的代码,重新部署到Heroku:
git add . git commit -m "Fix PostgreSQL connection for Heroku" git push heroku main
额外检查点
- 确保你的Gemfile里包含
pggem,并且在生产环境下被加载:gem 'pg', group: :production gem 'sqlite3', group: :development - 执行
bundle install --without production在本地安装依赖,避免本地安装pg gem的问题
内容的提问来源于stack exchange,提问作者Pam
相关产品推荐
相关产品推荐

