部署到 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:loaddb/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 数据库的主要内容,如果未能解决你的问题,请参考以下文章

Heroku 管道提升 - 拉到存储库

如何将 Rails + Webpacker 应用程序部署到 Heroku?

如何删除 Github 环境

在 Heroku 中部署错误:es 不是有效的语言环境

如何部署到 Apollo Graphql 服务器和客户端到生产环境?

如何直接从我的 Gitlab 存储库部署到 Heroku