Schema: load vs

这里有一个非常简单的问题——如果迁移可以变得缓慢和麻烦,因为应用程序变得更加复杂,而且如果我们有更干净的 rake db:schema:load来调用,那么为什么还有迁移存在呢?

如果上述问题的答案是迁移用于版本控制(数据库变更的逐步记录) ,那么随着应用程序变得越来越复杂,rake db:schema:load的使用越来越多,它们是否继续保持其主要功能?


注意:

从这个问题的答案来看: rake db:schema:load 将删除数据在生产服务器上,因此在使用它时要小心。

104879 次浏览

因为迁移可以回滚,并提供额外的功能。例如,如果需要修改某些数据作为模式更改的一部分,那么就需要将其作为迁移进行修改。

迁移也允许您向 db 添加数据。但是 db: schema: load 只加载模式。

迁移为数据库提供向前和向后的步骤更改。在生产环境中,必须在部署期间对数据库进行增量更改: 迁移为此功能提供了回滚故障保护。如果在生产服务器上运行 rake db:schema:load,最终将删除所有生产数据。养成这种习惯很危险。

话虽如此,我相信偶尔“崩溃”迁移是一种体面的做法。这需要删除旧的迁移,用一个迁移替换它们(非常类似于您的 schema.rb文件) ,并更新 schema_migrations表以反映此更改。这样做的时候要非常小心! 如果不小心的话,很容易删除生产数据。

顺便说一句,我强烈认为您永远不应该将数据创建放在迁移文件中。seed.rb文件可用于此目的,也可用于自定义 rake 或部署任务。将其放入迁移文件中会混合数据库模式规范和数据规范,并且在运行迁移文件时可能会导致冲突。

作为其他 ORM 的用户,Rails 没有“同步和更新”功能对我来说总是很奇怪。例如,通过使用模式文件(表示整个最新模式) ,遍历现有的 DB 结构并根据需要添加/删除表、列和索引。

对我来说,这将是一个更加强大的,即使可能有点慢。

只是偶然发现了这个帖子,那是很久以前的事了,没有看到我期待的答案。

在第一次将系统投入生产环境时,rake db:schema:load非常棒,之后您应该正常地运行迁移。

这也可以帮助您随时清理您的迁移,因为模式拥有将其他机器投入生产的所有信息,即使您已经清理了您的迁移。

我已经将其作为注释发布了,但是觉得最好将 db/schema.rb 文件的注释放在这里:

# Note that this schema.rb definition is the authoritative source for your
# database schema. 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).
#
# It's strongly recommended that you check this file into your version control system.

实际上,我的经验是,最好将迁移文件放在 git 中,而不是 schema.rb 文件中..。

rake db:migrate设置数据库中的表。当您运行迁移命令时,它将在 db/shift/中查找任何 ruby 文件,并从最旧的文件开始执行它们。每个迁移文件名的开头都有一个时间戳。

与运行尚未运行的迁移的 rake db:migrate不同,rake db:schema:loaddb/schema.rb中已经生成的模式加载到数据库中。

你可以了解更多有关 这里是 rake 数据库命令的资料。

因此 schema: load 获取当前配置的 schema,派生要匹配的关联查询,并一次运行所有查询。这是一劳永逸的事。正如您所看到的,迁移一步一步地进行更改。在本地处理项目时,加载模式可能是有意义的,特别是在项目生命周期的早期。但是,如果我们每次执行部署时都放弃并重新创建生产数据库,那么 我们每次都会丢失生产数据。不行。因此,这就是为什么我们使用迁移来对现有数据库进行所需的更改。

那么。随着对数据库进行更多的更改,对项目进行的更深入的研究将会产生更多的迁移。随着每次迁移的进行,这些迁移越来越成为生产环境中真相的来源——重要的不是模式中的内容,而是在生产环境中运行的迁移。如果我们两者同步的话,这种差异实际上是无意义的。但是一旦其中一个与另一个过时,你就会开始出现差异。理想情况下,这种情况不会发生,但我们生活在现实世界中,事情就会发生。如果使用 schema: load 在本地设置数据库,则可能无法获得数据库的实际状态,因为它通过生产上的迁移历史反映出来。