假设我有一个包含一堆迁移文件的应用程序,我正准备第一次将其部署到生产环境。据我了解,我基本上有两个选项可以在生产服务器上启动数据库:
- A - 运行
db:migrate
,并让它循环浏览尚未运行的所有迁移 - B - 运行
db:schema:load
,并让它从架构文件构建数据库
我知道 B 是新部署的正确选择,如schema.rb
评论中所述:
# If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
我想知道的是,这对生产服务器上的迁移有何影响?例如,如果我按顺序执行以下操作:
- 在新的生产服务器上运行
db:schema:load
。 - 在开发中更改我的架构并推送到生产环境。
- 在生产服务器上运行
db:migrate
会发生什么?它是否知道仅使用比db:schema:load
操作更新的迁移,还是会尝试运行所有迁移?
好问题。答案是,只有在最新db:schema:load
事件之后创建的迁移才会运行。
schema.rb 文件具有与之关联的版本戳:
ActiveRecord::Schema.define(version: 20130928225041) do ...
当您运行 db:schema:load
时,Rails 会根据该 schema.rb 文件创建一个新的数据库,同时使用版本号在 schema 之前的所有迁移填充schema_migrations
表。
因此,据我所知,Rails基本上是在伪造在此之前的所有迁移,但实际上并没有运行它们。(我通过生成一个空的迁移文件,在本地调用db:migrate
,然后在迁移到我们的服务器之前在迁移文件中插入一个错误来测试这一点。在服务器上,我们运行了db:schema:load
,结果是错误的迁移包含在schema_migrations表中,就好像它已经运行一样,即使它显然没有运行。