部署到 Heroku 时如何在我的生产环境中拥有一个 mysql 数据库
Posted
技术标签:
【中文标题】部署到 Heroku 时如何在我的生产环境中拥有一个 mysql 数据库【英文标题】:How to have a mysql database in my production environment when deployed to Heroku 【发布时间】:2021-09-17 16:16:21 【问题描述】:我有一个已部署到 heroku 的 Rails 应用程序,但我不知道如何为生产环境创建一个 mysql 数据库。 (本地环境的mysql数据库已经创建没有问题。)
问题1: 这是heroku配置的一些部分。您可以在下面看到 CLEARDB_DATABASE_URL 和 DATABASE_URL 共享同一个主机,但其他部分不同。哪个应该包含在database.yml的生产部分?
$ heroku config
=== exampleapp Config Vars
CLEARDB_DATABASE_URL:mysql://<username1>:<password1>@<host1>/<database1>?reconnect=true
DATABASE_URL:mysql2://<username2>:<password2>@<host1>/<database2>?reconnect=true
这是我的 database.yml。 (我已经包含了 CLEARDB_DATABASE_URL 的用户名、主机和密码。)
default: &default
pool: 5
timeout: 5000
development:
<<: *default
adapter: mysql2
database: exampleapp
pool: 5
timeout: 5000
username: root
password: xxx
host: localhost
production:
<<: *default
adapter: mysql2
database: exampleapp
username: <username1>
host: <host1>
password: <password1>
问题2: 我已经运行了“heroku run rails db:migrate”,但是没有创建表,即使所有必要的迁移文件都是在我的存储库的 db/migrate 目录下创建的。 当我检查 mysql 的 heroku 生产环境时(这是正确的检查方法吗?),发生了这样的事情;
$ mysql -u <username1> -p -h <host1> //username and host of CLEARDB_DATABASE_URL
$ mysql> show tables;
Empty set (0.18sec)
如果我在这里使用 SQL 从头开始创建表,它们会链接到应用程序吗? (CREATE TABLE db_name.tbl_name (col_name data_type,...)
等)
我有一整套本地环境的数据库,所以如果我可以将带有数据的表移动到生产环境中,那就太好了。有什么方法可以做到吗?
【问题讨论】:
【参考方案1】:对于生产系统,最佳做法是从环境变量中提取数据库信息,而不是在config/database.yml
中硬编码它们。这就是为什么在 Heroku 中设置 DATABASE_URL
环境变量的原因。您可以像这样在config/database.yml
中访问它:
production:
<<: *default
adapter: mysql2
url: <%= ENV['DATABASE_URL'] %>
其次,db:migrate
针对现有数据库运行迁移,但不会创建它。如果您使用的是 6.0 之前的 Rails 版本,则需要执行三个任务来设置新数据库:
% heroku run rails db:create
% heroku run rails db:schema:load
% heroku run rails db:seed
db:create
任务创建数据库,db:schema:load
从db/schema.rb
初始化您的应用表,db:seed
使用您在db/seeds.rb
中输入的任何内容为数据库播种
Rails 6+ 添加了一个db:prepare
任务,将创建任务合并为一个:
% heroku run rails db:prepare
【讨论】:
【参考方案2】:如上所述。我们不应该在代码中硬编码数据库细节因为这些信息会在 ClearDB 升级数据库的情况下更新。这应该从环境变量中提取。从 ENV 的完整 URL 中,我们可以提取如下详细信息
require 'uri'
database_url = URI.parse(ENV['DATABASE_URL'])
user_info = database_url.userinfo.split(':')
default: &default
pool: 5
timeout: 5000
development:
<<: *default
adapter: mysql2
database: database_url.path[1..-1]
pool: 5
timeout: 5000
username: user_info.first
password: user_info.last
host: database_url.host
对于第二个问题,您能否检查一下您的 schema.rb。是否拥有生产所需的所有表格
【讨论】:
非常感谢您的评论!!我学会了使用 ENV 编写 database.yml。我的 schema.rb 有所有需要的表。谢谢!!以上是关于部署到 Heroku 时如何在我的生产环境中拥有一个 mysql 数据库的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Rails + Webpacker 应用程序部署到 Heroku?