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

720

rake db:migraterake db:reset的区别对我来说很清楚。 我不理解的是rake db:schema:load与前两者的区别。

为了确保我们在同一个页面上:

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

13
rake --tasks 有帮助吗? - zx1986
你应该查看这个博客。http://jacopretorius.net/2014/02/all-rails-db-rake-tasks-and-what-they-do.html - Bishisht Bhatta
你对 rake db:migrate 的理解是正确的,但你对 rake db:reset 的理解是错误的。请参考来自moritz的最佳答案。 - Magne
2
顺便提一下,从Rails 5开始,这些命令可以被调用为rails db:migraterails db:resetrails db:schema:load。请参见https://dev59.com/VFoT5IYBdhLWcg3wlgXn。 - Purplejacket
6个回答

1517
  • 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:create 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)。

    23
    这是答案文件 :) - https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railties/databases.rake - cutalion
    3
    @cutation: db:setup 不会运行 db:migrate,因为为了进行数据库设置而运行所有迁移将会非常脆弱(这就是 schema.rb 的作用)。 - moritz
    2
    我正在执行db:reset命令,它正在填充我的数据库。这是为什么? - Alejandro Riedel
    1
    db:setup 如果需要的话也会运行 db:create。至少在 Rails 4.0.2 中是这样的。 - Dan
    我刚刚在一个新的Rails v6.0.0项目中运行了rake db:setup命令,但是收到了消息“db/schema.rb文件还不存在。运行rails db:migrate来创建它,然后再试一次”,因此似乎这个版本不会运行db:migrate命令。 - ian
    显示剩余7条评论

    27

    TLDR

    使用:

    • rake db:migrate 如果你想要更改架构
    • rake db:reset 如果你想要删除数据库、从 schema.rb 重载架构,并重新填充数据库
    • rake db:schema:load 如果你想要将数据库重置为schema.rb中提供的架构(这将删除所有数据)

    Explanations

    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(从一系列先前的迁移创建)创建生产模式,那么 rake 是否会知道哪些迁移(参与创建初始 schema.rb 的迁移)不需要在未来调用 db:migrate 时运行? - user3096803

    12

    Rails 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:up 或者 db:migrate:rollbackdb:migrate:up

    db:migrate:up - 运行给定迁移版本的 up 操作。

    db:migrate:down - 运行给定迁移版本的 down 操作。

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

    db:migrate:rollback - 回滚最后一次迁移。

    db:version - 显示当前模式版本。

    db:forward - 推进模式到下一个版本。

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

    db:schema:load - 从 schema.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:create db:schema:load db:seed

    db:reset - 运行 db:drop db:setup db:migrate:reset - 运行 db:drop db:create db: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等破坏性操作时内部使用。


    3

    列出所有任务

    你可以在 Rails 应用程序目录中运行以下命令来查找 Rails 提供的所有数据库任务。

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

    概述

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

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

    db:environment:set: 通过在内部表中设置当前环境来修复EnvironmentMismatchErrorNoEnvironmentInSchemaError,如果环境数据未在模式中找到。

    db:fixtures:load: 加载样本数据(也称为固定资产),以便进行测试。这些数据存储在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.yml文件,该文件由db:schema:cache:dump任务生成。

    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。不开玩笑,真的

    db:system:change: 运行未指定数据库的rails new生成器将应用程序设置为 sqlite。稍后更改数据库很麻烦。此任务通过委托给rails db:change SYSTEM=postgresql|mysql|whatever 生成器来帮助您轻松更改数据库。

    db:version: 打印当前模式版本号。

    来源:Rails 中的所有数据库任务


    2
    据我所了解,这将会删除你的数据库并基于你的 db/schema.rb 文件重新创建它。因此,你需要确保你的 schema.rb 文件始终是最新的,并且处于版本控制之下。

    0

    你可以直接查看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方面做得非常好,但并不总是很好地记录代码。如果我们知道它应该做什么,我们都可以在那里提供帮助。


    请在文章中引用相关部分,以防被删除。不要建议做某事而不解释原因。 - PhilT

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接