【问题标题】:Purge or recreate a Ruby on Rails database清除或重新创建 Ruby on Rails 数据库
【发布时间】:2011-05-06 04:32:30
【问题描述】:

我有一个充满数据的开发 Ruby on Rails 数据库。我想删除所有内容并重建数据库。我正在考虑使用类似的东西:

rake db:recreate

这可能吗?

【问题讨论】:

  • 我建议跳过投票率最高的答案。在我看来rake db:drop db:create db:schema:load 可能比rake db:drop db:create db:migrate 更合适(尽管我已经准备好在这点上犯错了)。
  • rake db:drop db:create db:migrate
  • db:drop + db:create + db:migrate == db:migrate:reset。当迁移被破坏时,我通常求助于db:schema:load。我很少需要重新创建数据库,所以速度并不重要。此外,如果您有未应用的迁移,db:schema:loaddb:reset 将不会应用它们。不确定这是否是一个很大的争论。

标签: ruby-on-rails ruby-on-rails-3 rake


【解决方案1】:

根据您的需求,您可以使用...

rake db:create

…从config/database.yml 开始构建数据库,或者…

rake db:schema:load

...从您的 schema.rb 文件从头开始构建数据库。

【讨论】:

  • 您必须先删除数据库……或者如果您愿意,也可以删除表。
  • +1 用于模式加载。有时迁移会搞砸,但架构应该保持完整。
  • 我在 Rails 3 Way 中读到加载模式是要走的路,而不是运行所有迁移。我不记得他们的推理究竟是什么,但它似乎是有道理的。如果无论哪种方式最终结果都相同,那么从架构中加载数据库似乎比运行一堆迁移更简单且不易出错。
  • 原因是迁移是为了迁移数据,并且随着模型的变化而变得越来越脆弱。您可以(并且应该)在可行的情况下将最低限度的范围模型烘焙到您的迁移中以确保它们运行,但这只是不能很好地扩展并且比仅从应用程序知道的最后一点构建数据库效率低得多.当您可以从蓝图本身构建时,为什么还要依赖迁移来创建看起来像您的架构的数据库?
【解决方案2】:

我在终端中使用以下一种班轮。

$ rake db:drop && rake db:create && rake db:migrate && rake db:schema:dump && rake db:test:prepare

我把它作为一个shell别名并命名为remigrate

现在,您可以轻松地“链接”Rails 任务:

$ rake db:drop db:create db:migrate db:schema:dump db:test:prepare # db:test:prepare no longer available since Rails 4.1.0.rc1+

【讨论】:

  • 这将一个接一个地运行您的所有迁移,这是不可扩展的并且容易出错。另外,我很确定 db:migrate 会更新你的 schema.rb,所以你的 schema:dump 没有做任何有用的事情。
  • 那么如何清空数据库呢?正在开发中...清除所有内容。
  • @AnApprentice 你可以运行db:reset,这只是一个谷歌(或查看Guides)。我的评论并不是建议不要使用它,而是要避免在您真正想要的是 db:schema:load 时使用 db:migrate
  • 顺便说一句,@TK,您真的不需要根据最后一个退出状态将所有这些作为单独的进程运行。相反,只需将所有需要的任务传递给rake,如下所示:rake db:drop db:create db:schema:load
  • 这是轶事,但我从来没有遇到过运行 db:migrate 的问题...而 db:schema:load 对忘记将 schema.rb 签入版本控制以及新迁移的人很敏感。跨度>
【解决方案3】:

我知道两种方法:

这将重置您的数据库并重新加载您当前的架构:

rake db:reset db:migrate

这将破坏您的数据库,然后创建它,然后迁移您当前的架构:

rake db:drop db:create db:migrate

在这两种情况下所有数据都将丢失。

【讨论】:

  • 看来rake db:reset 也运行所有迁移(至少在 Rails 3 上),所以这应该是所需要的,对吧?
  • 或者,更确切地说,它使架构与运行所有迁移的架构相同。但是迁移本身并没有运行(因此,如果您有插入数据的迁移,则不会发生这种情况;为此,您应该真正使用 db/seeds.rb 文件)。
  • 我知道对于 Tracks GTD 应用程序 db:migrate 不起作用。从 Sqlite3 迁移到 Postgres 时,我必须执行 db:reset。
  • 您还需要运行rake db:test:prepare 进行测试,否则您会收到如下错误:Could not find table 'things' (ActiveRecord::StatementInvalid)
  • 有人应该明确指出rake db:resetrake db:drop db:create db:migrate 做两件完全不同的事情。后者清除整个应用程序数据库,重新创建它,然后通过每次迁移来更新架构(db/schema.rbdb/structure.sql),但不会用种子数据填充它。第一个是rake db:drop db:schema:load db:seed 的别名,因此它会清除整个应用程序数据库,但它不更新架构,然后填充种子数据。因此,如果您在迁移中没有更改任何内容,则前者更快,后者更安​​全。
【解决方案4】:

我今天对我的 rails 架构进行了很多更改。我意识到我需要在层次结构中增加两个模型,并删除其他一些模型。模型和控制器需要做很多小改动。

我添加了两个新模型并创建了它们,使用:

rake db:migrate

然后我编辑了 schema.rb 文件。我手动删除了不再需要的旧模型,根据需要更改了外键字段,并对其进行了重新排序以使我更清楚。我删除了所有迁移,然后通过以下方式重新运行构建:

rake db:reset

效果很好。当然,所有数据都必须重新加载。 Rails 意识到迁移已被删除并重置高水位线:

-- assume_migrated_upto_version(20121026094813, ["/Users/sean/rails/f4/db/migrate"])

【讨论】:

    【解决方案5】:

    您可以使用以下命令行:

    rake db:drop db:create db:migrate db:seed db:test:clone
    

    【讨论】:

      【解决方案6】:

      根据Rails guide,应该使用这一行,因为它会从schema.rb 加载,而不是一一重新加载迁移文件:

      rake db:reset
      

      【讨论】:

        【解决方案7】:

        你可以手动做:

        rake db:drop
        rake db:create
        rake db:migrate
        

        或者只是rake db:reset,它将运行上述步骤,但也会运行您的db/seeds.rb 文件。

        另一个细微差别是 rake db:reset 直接从您的 schema.rb 文件加载,而不是再次运行所有迁移文件。

        您的数据在所有情况下都会被吹走。

        【讨论】:

          【解决方案8】:

          要删除特定数据库,您可以在 rails 控制台上执行此操作:

          $rails console
          Loading development environment
          1.9.3 > ActiveRecord::Migration.drop_table(:<table_name>)
          1.9.3 > exit
          

          然后再次迁移数据库

          $bundle exec rake db:migrate 
          

          【讨论】:

            【解决方案9】:

            从命令行运行

            rake db:migrate:reset
            

            【讨论】:

            • 这是使应用再次运行所有迁移的唯一方法。因为每次迁移都会更改schema.rb,如果您只有dropcreatemigrate 将什么也不做(在 rails 6 上测试)
            【解决方案10】:

            在 Rails 4 上,只需要

            $ rake db:schema:load
            

            这将删除数据库上的全部内容并从 schema.rb 文件重新创建架构,而无需一一应用所有迁移。

            【讨论】:

            • 也适用于 rails 3。当您刚刚弄乱了测试数据库并希望将其重置为与您的开发数据库匹配的工作版本时很有用
            • 谢谢。我没有意识到db:dropdb:create 是多余的。
            • 这不会更新架构,如果您重构迁移,这不是一种安全的方式。
            • 确保架构是最新的。有时人们提交迁移文件但跳过提交对 schema.rb 文件的更改,因为他们没有意识到这意味着什么。
            • @ClaudioFloreani 重构迁移是自找麻烦。一旦它们运行,它们就应该被永久地单独放置。
            【解决方案11】:

            只需发布步骤顺序:删除数据库,然后重新创建它,迁移数据,如果有种子,播种数据库:

            rake db:drop db:create db:migrate db:seed
            

            由于rake 的默认环境是development,如果您在规范测试中看到异常,您应该为test 环境重新创建db如下:

            RAILS_ENV=test rake db:drop db:create db:migrate
            

            在大多数情况下,测试数据库是在测试过程中播种的,因此不需要通过db:seed 任务操作。否则,你应该准备数据库:

            rake db:test:prepare
            

            RAILS_ENV=test rake db:seed
            

            此外,要使用 recreate 任务,您可以将以下代码添加到 Rakefile 中:

            namespace :db do
               task :recreate => [ :drop, :create, :migrate ] do
                  if ENV[ 'RAILS_ENV' ] !~ /test|cucumber/
                     Rake::Task[ 'db:seed' ].invoke
                  end
               end
            end
            

            然后发出:

            rake db:recreate
            

            【讨论】:

              【解决方案12】:

              像这样使用

              rake db:drop db:create db:migrate db:seed
              

              全部在一条线上。这更快,因为环境不会一次又一次地重新加载。

              db:drop - 将删除数据库。

              db:create - 将创建数据库(host/db/password 将从 config/database.yml 获取)

              db:migrate - 将从目录 (db/migration/.rb)* 运行现有迁移。

              db:seed - 将可能从目录 (db/migration/seed.rb)..

              运行种子数据

              我通常更喜欢:

              rake db:reset
              

              一次性完成。

              干杯!

              【讨论】:

              • 我喜欢将 db:test:prepare 添加到此,这是一个很好的衡量标准。当然,这取决于您是否在测试。
              • db:reset == db:drop + db:schema:load + db:seed, db:migrate:reset == db:drop + db:create + db:migrate
              【解决方案13】:

              更新:在 Rails 5 中,可以通过以下命令访问此命令:

              rails db:purge db:create db:migrate RAILS_ENV=test


              从最新的 rails 4.2 版本开始,您现在可以运行:

              rake db:purge 
              

              来源:commit

              # desc "Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases."
                task :purge => [:load_config] do
                  ActiveRecord::Tasks::DatabaseTasks.purge_current
                end
              

              可以像上面提到的那样一起使用:

              rake db:purge db:create db:migrate RAILS_ENV=test
              

              【讨论】:

              • 正如@bekicot 用更简单的英语所说的db:purge“删除所有数据但保留所有表和列”
              • @MCB 我错了,抱歉,db:purge 没有保留表格。
              【解决方案14】:

              在 Rails 4.2 上,删除所有数据但保留数据库

              $ bin/rake db:purge && bin/rake db:schema:load
              

              https://github.com/rails/rails/blob/4-2-stable/activerecord/CHANGELOG.md

              【讨论】:

              • 嗯...刚试过,但它不保留表和列。在运行 db:purge 之后,您必须运行 db:migrate。所以这不会保留表和列。但是,它确实保留了数据库本身,因此您不必 db:create
              • @Cedric 你是对的, db:purge 不是保留表。我更新了代码。
              【解决方案15】:

              因为在开发中,你总是想重新创建数据库,你可以像这样在你的 lib/tasks 文件夹中定义一个 rake 任务。

                namespace :db do
                    task :all => [:environment, :drop, :create, :migrate] do
                 end 
              end
              

              你会在终端运行

              rake db:all
              

              它将重建您的数据库

              【讨论】:

                【解决方案16】:

                我认为运行此命令的最佳方式:

                **rake db:reset** it does db:drop, db:setup
                 rake db:setup does db:create, db:schema:load, db:seed
                

                【讨论】:

                  【解决方案17】:

                  你可以使用 db:reset - 用于运行 db:drop 和 db:setup 或 db:migrate:reset - 运行 db:drop、db:create 和 db:migrate。

                  依赖于你想使用的现有 schema.rb

                  【讨论】:

                    【解决方案18】:

                    你可以运行

                    rake db:setup

                    如果您使用一些数据创建种子文件,它将删除数据库,创建新数据库并从种子填充数据库。

                    【讨论】:

                      【解决方案19】:

                      3 个选项,结果相同:

                      1.所有步骤:

                        $ rake db:drop           # deletes the database for the current env
                        $ rake db:create         # creates the database for the current env
                        $ rake db:schema:load    # loads the schema already generated from schema.rb / erases data
                        $ rake db:seed           # seed with initial data
                      

                      2.重置:

                        $ rake db:reset          # drop / schema:load / seed
                      

                      3. 迁移:重置:

                        $ rake db:migrate:reset  # drop / create / migrate
                        $ rake db:seed
                      

                      注意事项:

                      • 如果使用 schema:load 比执行所有迁移更快,但结果相同。
                      • 所有数据都将丢失。
                      • 您可以在一行中运行多个 rake。
                      • 适用于导​​轨 3。

                      【讨论】:

                        【解决方案20】:

                        在 Rails 6 中,有一种方便的方法可以重置 DB 并再次播种:

                        rails db:seed:replant # Truncates tables of each database for current environment and loads the seeds
                        

                        https://weblog.rubyonrails.org/2019/3/15/this-week-in-rails-security-fixes-bulk-insert-and-upsert-seeds-replanting/

                        【讨论】:

                          【解决方案21】:

                          我用:

                          • rails db:drop 删除数据库。
                          • rails db:create 创建基于config/database.yml 的数据库

                          前面的命令可以替换为rails db:reset

                          不要忘记运行 rails db:migrate 来运行迁移。

                          【讨论】:

                            猜你喜欢
                            • 2019-05-09
                            • 2023-04-03
                            • 2017-01-15
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2020-10-05
                            • 2016-06-11
                            • 1970-01-01
                            相关资源
                            最近更新 更多