rake db:migrate db:reset 和 db:schema:load 之间的区别

Posted

技术标签:

【中文标题】rake db:migrate db:reset 和 db:schema:load 之间的区别【英文标题】:Difference between rake db:migrate db:reset and db:schema:load 【发布时间】:2012-05-05 07:39:17 【问题描述】:

rake db:migraterake db:reset 之间的区别在我脑海中非常清楚。我不明白的是rake db:schema:load与前两者有何不同。

只是为了确保我在同一页面上:

rake db:migrate - 运行尚未运行的迁移。 rake db:reset - 清除数据库(可能是 rake db:drop + rake db:create + rake db:migrate)并在新数据库上运行迁移。

如果我的理解有误,请帮助澄清。

【问题讨论】:

rake --tasks 有帮助吗? 你应该看看这个博客。 jacopretorius.net/2014/02/… 你对rake db:migrate的理解是正确的,但是你对rake db:reset的理解是错误的。请参阅莫里茨的最高答案。 顺便说一句,从 Rails 5 开始,这些命令可以调用为 rails db:migraterails db:resetrails db:schema:load。见***.com/questions/38403533/… 【参考方案1】:

db:migrate 运行(单个)尚未运行的迁移。

db:create 创建数据库

db:drop 删除数据库

db:schema:load 在 schema.rb 之后的现有数据库中创建表和列。这将删除现有数据。

db:setup 执行 db:create, db:schema:load, db:seed

db:reset 执行 db:drop, db:setup

db:migrate:reset 执行 db:drop、db:create、db:migrate

通常,您会在通过新的迁移文件对架构进行更改后使用 db:migrate(这仅在数据库中已有数据时才有意义)。 db:schema:load 用于设置应用的新实例。

希望对你有帮助。


rails 3.2.12 更新:

我刚刚查了源码,现在依赖是这样的:

db:create 为当前环境创建数据库

db:create:all 为所有环境创建数据库

db:drop 删除当前环境的数据库

db:drop:all 删除所有环境的数据库

db:migrate 为尚未运行的当前环境运行迁移

db:migrate:up 运行一个特定的迁移

db:migrate:down 回滚一个特定的迁移

db:migrate:status 显示当前迁移状态

db:rollback 回滚上次迁移

db:forward 将当前架构版本推进到下一个版本

db:seed(仅)运行 db/seed.rb 文件

db:schema:load 将架构加载到当前环境的数据库中

db:schema:dump 转储当前环境的架构(并且似乎也创建了数据库)

db:setup 运行 db:schema:load、db:seed

db:reset 运行 db:drop db:setup

db:migrate:redo 根据指定的迁移运行 (db:migrate:down db:migrate:up) 或 (db:rollback db:migrate)

db:migrate:reset 运行 db:drop db:create db:migrate

如需更多信息,请查看https://github.com/rails/rails/blob/v3.2.12/activerecord/lib/active_record/railties/databases.rake(适用于 Rails 3.2.x)和https://github.com/rails/rails/blob/v4.0.5/activerecord/lib/active_record/railties/databases.rake(适用于 Rails 4.0.x)

【讨论】:

这是带有答案的文件 :) - github.com/rails/rails/blob/master/activerecord/lib/… @cutation: db:setup 肯定不会运行 db:migrate,因为仅仅为一个 db 设置运行所有迁移太脆弱了(这就是 schema.rb 的用途)。 我正在执行 db:reset 并且它正在播种我的数据库。为什么会这样? db:setup 也会在必要时运行 db:create。至少从 rails 4.0.2 开始。 Rails 4 将在调用 rake db:setup 时执行 rake db:migrate,如果有挂起的迁移但不会执行挂起的迁移。【参考方案2】:

TLDR

使用

rake db:migrate 如果您想更改架构 rake db:reset 如果要删除数据库,请从 schema.rb 重新加载架构,然后重新设置数据库的种子 rake db:schema:load 如果您想将数据库重置为schema.rb 中提供的架构(这将删除所有数据)

说明

rake db:schema:load 将设置schema.rb 文件中提供的架构。这对于全新安装应用程序很有用,因为它不需要像 db:migrate 那么多的时间

重要提示,db:schema:load删除服务器上的数据。

rake db:migrate 对现有架构进行更改。就像创建模式的版本一样。 db:migrate 将在 db/migrate/ 中查找任何 ruby​​ 文件,并从最旧的文件开始执行尚未运行的迁移。 Rails 通过查看迁移文件名开头的时间戳来知道哪个文件最旧。 db:migrate 带来的好处是数据也可以放入数据库中。这实际上不是一个好习惯。最好使用rake db:seed添加数据。

rake db:migrate 提供任务up、down 等,可以启用rake db:rollback 等命令并使其成为最有用的命令。

rake db:reset 执行 db:dropdb:setup 它删除数据库,再次创建它,加载架构,并使用种子数据进行初始化

来自databases.rake的相关部分命令


namespace :schema do
  desc 'Creates a db/schema.rb file that is portable against any DB supported by Active Record'
  task :dump => [:environment, :load_config] do
    require 'active_record/schema_dumper'
    filename = ENV['SCHEMA'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, 'schema.rb')
    File.open(filename, "w:utf-8") do |file|
      ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
    end
    db_namespace['schema:dump'].reenable
  end

  desc 'Loads a schema.rb file into the database'
  task :load => [:environment, :load_config, :check_protected_environments] do
    ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:ruby, ENV['SCHEMA'])
  end

  # desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.'
  task :reset => [ 'db:drop', 'db:setup' ]

namespace :migrate do
  # desc  'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
  task :redo => [:environment, :load_config] do
    if ENV['VERSION']
      db_namespace['migrate:down'].invoke
      db_namespace['migrate:up'].invoke
    else
      db_namespace['rollback'].invoke
      db_namespace['migrate'].invoke
    end
  end

【讨论】:

因此,如果您使用 db:schema:load(从一系列以前的迁移创建)创建生产模式,将了解哪些迁移(参与创建初始 schema.rb 的迁移)不需要在未来调用 db:migrate 时运行?【参考方案3】:

导轨 5

db:create - 为当前 RAILS_ENV 环境创建数据库。如果未指定 RAILS_ENV,则默认为开发和测试数据库。

db:create:all - 为所有环境创建数据库。

db:drop - 删除当前 RAILS_ENV 环境的数据库。如果未指定 RAILS_ENV,则默认为开发和测试数据库。

db:drop:all - 删除所有环境的数据库。

db:migrate - 为尚未运行的当前环境运行迁移。默认情况下,它只会在开发环境中运行迁移。

db:migrate:redo - 运行 db:migrate:downdb:migrate:updb:migrate:rollback db:migrate:up 取决于指定的迁移。

db:migrate:up - 为给定的迁移 VERSION 运行 up。

db:migrate:down - 为给定的迁移 VERSION 运行 down。

db:migrate:status - 显示当前迁移状态。

db:migrate:rollback - 回滚上次迁移。

db:version - 打印当前架构版本。

db:forward - 将架构推送到下一个版本。

db:seed - 运行 db/seeds.rb 文件。

db:schema:loadschema.rb 文件重新创建数据库。 删除现有数据。

db:schema:dump 将当前环境的架构转储到 db/schema.rb

db:structure:load - 从 structure.sql 文件重新创建数据库。

db:structure:dump - 将当前环境的架构转储到 db/structure.sql。 (你可以用SCHEMA=db/my_structure.sql指定另一个文件)

db:setup 运行 db:createdb:schema:loaddb:seed

db:reset 运行 db:dropdb:setupdb:migrate:reset - 运行 db:dropdb:createdb:migrate

db:test:prepare - 检查挂起的迁移并加载测试模式。 (如果你在没有任何参数的情况下运行 rake,它会默认这样做。)

db:test:clone - 从当前环境的数据库架构重新创建测试数据库。

db:test:clone_structure - 类似于 db:test:clone,但它将确保您的测试数据库与您当前环境的数据库具有相同的结构,包括字符集和排序规则。

db:environment:set - 在 ar_internal_metadata 表中设置当前的 RAILS_ENV 环境。 (用作受保护环境检查的一部分。)

db:check_protected_environments - 检查是否可以在当前 RAILS_ENV 环境中执行破坏性操作。在运行诸如 db:dropdb:schema:load 等破坏性操作时在内部使用。

【讨论】:

【参考方案4】:

据我了解,它将删除您的数据库并根据您的 db/schema.rb 文件重新创建它。这就是为什么您需要确保您的 schema.rb 文件始终是最新的并处于版本控制之下。

【讨论】:

【参考方案5】:

您可以简单地查看 Active Record Rake 任务,因为我相信它们在此文件中存在。 https://github.com/rails/rails/blob/fe1f4b2ad56f010a4e9b93d547d63a15953d9dc2/activerecord/lib/active_record/tasks/database_tasks.rb

你的问题对吗?

这取决于它们来自哪里,这只是一个示例,表明它们因任务而异。这里我们有一个不同的文件,里面装满了任务。

https://github.com/rails/rails/blob/fe1f4b2ad56f010a4e9b93d547d63a15953d9dc2/activerecord/Rakefile

有这些任务。

namespace :db do
  task create: ["db:mysql:build", "db:postgresql:build"]
  task drop: ["db:mysql:drop", "db:postgresql:drop"]
end

这可能无法回答您的问题,但可以让您深入了解继续查看源代码,尤其是 rake 文件和任务。由于他们在帮助您使用 Rails 方面做得很好,他们并不总是能很好地记录代码。如果我们知道它应该做什么,我们都可以在那里提供帮助。

【讨论】:

请引用文章的相关部分,以防被删除。不要在没有解释原因的情况下建议做某事。【参考方案6】:

列出所有任务

您可以通过从 Rails 应用程序目录运行以下命令来找到 Rails 提供的所有数据库任务。

➜  blog (main) ✗ bin/rails help | grep db:

db:create
db:drop
...

总结

db:create:创建数据库,除非它已经存在。

db:drop:如果数据库存在则删除它。

db:environment:set:通过在内部表中设置当前环境来修复EnvironmentMismatchErrorNoEnvironmentInSchemaError,如果在架构中找不到环境数据,则会引发。 p>

db:fixtures:load:加载fixtures,即你想要测试的样本数据。它们存储在 test/fixtures/ 目录下的 YAML 文件中。

db:migrate:为当前环境运行所有尚未运行的迁移。

db:migrate:down:通过运行down 方法恢复上次迁移的up 方法执行的转换。

db:migrate:redo:回滚数据库一次迁移并重新向上迁移。

db:migrate:status:显示迁移状态。

db:migrate:up:为给定的迁移运行 up 方法。

db:prepare:如果数据库不存在,则运行 setup。否则,它会运行迁移。

db:reset:使用当前环境的迁移重置数据库。它通过运行db:dropdb:createdb:migrate 任务来做到这一点。

db:rollback:将架构回滚到以前的版本,撤消刚刚运行的迁移。如果您想撤消之前的 n 迁移,请将 STEP=n 传递给此任务。

db:schema:cache:clear:清除db:schema:cache:dump任务生成的db/schema_cache.yml文件。

db:schema:cache:dump:创建一个 db/schema_cache.yml 文件。

db:schema:dump:创建数据库模式文件(db/schema.rbdb/structure.sql,取决于 config.active_record.schema_format)。

db:schema:load:将数据库架构文件(db/schema.rbdb/structure.sql,取决于 config.active_record.schema_format)加载到数据库中。

db:seed:从db/seeds.rb 文件加载种子数据。

db:seed:replant:为当前环境截断每个数据库的表并加载种子

db:setup:创建所有数据库db:create,加载所有架构db:schema:load,并使用种子数据db:seed 进行初始化。但是,如果它存在,它不会首先删除数据库。使用db:reset 也可以先删除所有数据库。

db:structure:dump:已弃用。它用于转储structure.sql 文件。 db:structure:load:已弃用。它用于加载structure.sql 文件。

有关这些任务被弃用的原因,请查看wtf。不,seriously。

db:system:change:在不指定数据库的情况下运行 rails new 生成器会将您的应用设置为 sqlite。以后改数据库很麻烦。此任务通过委派给rails db:change SYSTEM=postgresql|mysql|whatever 生成器来帮助您轻松更改数据库。

db:version:打印当前架构版本号。

来源:All the Database Tasks in Rails

【讨论】:

以上是关于rake db:migrate db:reset 和 db:schema:load 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

为啥 rake db:migrate:reset 未在 rake -T 中列出?

如何运行 db:migrate 从另一个带参数的 rake 任务?

rake db:migrate不执行任何操作

如何使用 rake db:migrate 仅回滚一步

在 Heroku 上执行 rake db:migrate 时出错

使用 rake db:migrate 迁移数据不会改变它