635

I have a dev Ruby on Rails database full of data. I want to delete everything and rebuild the database. I'm thinking of using something like:

rake db:recreate

Is this possible?

random
  • 9,774
  • 10
  • 66
  • 83
AnApprentice
  • 108,152
  • 195
  • 629
  • 1,012
  • I'd suggest looking past the highest-upvoted answer. In my opinion `rake db:drop db:create db:schema:load` might be more appropriate than `rake db:drop db:create db:migrate` (although I'm ready to be wrong about that). – Jason Swett Jul 22 '15 at 18:38
  • Possible duplicate of [Reset the database (purge all), then seed a database](http://stackoverflow.com/questions/4003978/reset-the-database-purge-all-then-seed-a-database) – akostadinov Nov 25 '16 at 19:19
  • 2
    `rake db:drop db:create db:migrate` – Kyle Krzeski May 26 '18 at 19:35
  • `db:drop + db:create + db:migrate == db:migrate:reset`. I usually resort to `db:schema:load`, when migrations are broken. I rarely need to recreate database, so speed doesn't matter much. Also, if you have unapplied migrations, `db:schema:load` and `db:reset` won't apply them. Not sure if that's much of an argument. – x-yuri Jun 06 '18 at 20:26

22 Answers22

1177

I know two ways to do this:

This will reset your database and reload your current schema with all:

rake db:reset db:migrate

This will destroy your db and then create it and then migrate your current schema:

rake db:drop db:create db:migrate

All data will be lost in both scenarios.

Andrew Hendrie
  • 6,205
  • 4
  • 40
  • 71
thenengah
  • 42,557
  • 33
  • 113
  • 157
  • 38
    It seems `rake db:reset` also runs all migrations (at least on Rails 3), so that should be all that is needed, right? – plindberg Mar 22 '11 at 13:37
  • 2
    Or, rather, it leaves the schema identical to what running all the migrations would have. But the migrations aren't run per se (so if you have migrations which insert data, that won't happen; for this, you should really use a db/seeds.rb file). – plindberg Mar 22 '11 at 14:24
  • 1
    I know that for Tracks GTD app db:migrate didn't work. I had to do db:reset when moving from Sqlite3 to Postgres. – labyrinth Mar 29 '12 at 04:06
  • 11
    You'll also need to run `rake db:test:prepare` for testing, or else you'll get an error like: `Could not find table 'things' (ActiveRecord::StatementInvalid)` – s2t2 Feb 17 '13 at 01:49
  • Make sure there are no connections to db (web server, sql client...) otherwise drop won't work and shit will happen. – laffuste May 14 '13 at 13:24
  • I have found that drop, create then migrate is more consistent: I have some migrations that load constants in the db that were not loading correctly with the first solution. – Abdo Jul 17 '13 at 11:25
  • 1
    You should run `rake db:schema:load` instead of `rake db:migrate` whenever you a recreating a database. – Arel Aug 06 '13 at 20:32
  • @Abdo: you should use seeds to load content, migrations only for structure (or maybe modifying structure and existing data). Then `rake db:reset` will just fill the database with the latest schema. Much quicker. – nathanvda Oct 31 '13 at 15:54
  • For some reason db:reset just doesn't do anything for me. I have to explicitly drop and create. This is on Rails 4. – Suan Feb 28 '14 at 04:57
  • @Suan this is strange. For me `db:reset` did everything. I did not need to run `db:migrate` and `db:seed`, too. – gotqn Sep 15 '14 at 18:30
  • @s2t2 rake db:test:prepare checks and warns about pending migrations. Since he is doing db:migrate in each example, this is not needed. Also db:test:prepare is deprecated in 4.1.0. – John Pankowicz Oct 29 '14 at 13:27
  • See the rails 4.2 way below. – Robbie Guilfoyle Jan 02 '15 at 04:32
  • 1
    @nathandva In rails 3.2.13 `rake db:reset` also fills the db with the seed file – lbramos Jan 18 '15 at 22:59
  • @plindberg please remove your comment. It's terribly out of date and misinformative. – Darth Egregious Apr 28 '15 at 17:28
  • 46
    Someone should make clear that `rake db:reset` and `rake db:drop db:create db:migrate` **do two whole different things**. The latter wipes out the whole app database, recreates it and then goes through every migration to update the schema (`db/schema.rb` or `db/structure.sql`), but does not fill it with seed data. The first instead is an alias for `rake db:drop db:schema:load db:seed`, so it wipes out the whole app database but it **does not update the schema**, and then populates with seed data. So, if you haven't changed anything in your migrations, the first is quicker, the latter is safer. – Claudio Floreani Jul 08 '15 at 10:26
  • Don't use migrate as shown in the answer. It will work on smaller repositories and systems but usually as they grow, as some point a _data_ migration (as opposed to a _schema_ migration) gets included (bad) and an issue arises with the data migration which breaks the migrations ability to be re-run. At that point people usually switch to use `rake db:schema:load` instead. Instead of raging against such migrations placed by the infamous 'former developer' and insisting they be fixed, I now just use the `schema:load` approach and carry on with the rest of my work. – Michael Durrant Jun 17 '16 at 18:59
  • Thanks, @ClaudioFloreani! I was confused, why my changes in migration files doesn't apply when I run `db:reset`. – Dmitry Feb 04 '17 at 22:25
  • @ClaudioFloreani Why is the latter safer? Can you elaborate? – x-yuri Jun 06 '18 at 19:59
  • I also want to point out that `rake db:reset` does **not** adhere to any PostgreSQL (I have not tested other SQL) schemas you have setup. For example, if you are seeding your database and have schema `ABC` with data in table `XYZ` (in addition to regular `public` schema), `rake db:reset` **will repopulate `public.XYZ` NOT `ABC.XYZ`.** However, `rake db:drop`, `rake db:create`, `rake db:migrate` will add the seed data to the correct schema. – Jacob Miller Jun 04 '21 at 19:50
176

On Rails 4, all needed is

$ rake db:schema:load

That would delete the entire contents on your DB and recreate the schema from your schema.rb file, without having to apply all migrations one by one.

Eneko Alonso
  • 18,884
  • 9
  • 62
  • 84
  • 6
    works for rails 3 as well. useful for when you just messed up your test database and want to reset it to a working version that matches your dev db – bigpotato Feb 21 '14 at 19:56
  • Thanks for this. I didn't realize that `db:drop` and `db:create` were redundant. – Grant Birchmeier Jul 07 '14 at 22:20
  • 3
    This doesn't updates the schema, is not a safe way if you refactor your migrations. – Claudio Floreani Jul 08 '15 at 10:31
  • Make sure that schema is up to date. Sometimes people commit migration files but skip committing the changes to the schema.rb file because they dont realize what it means. – Yoni Jun 08 '16 at 22:01
  • 3
    @ClaudioFloreani refactoring migrations is asking for trouble. Once they're run, they should be left alone, permanently. – zzz Oct 25 '16 at 17:06
  • @nrowegt Refactoring migration is encouraged indeed (especially during development) — if done with awarness of the facts. Read more about ["AntiPattern: Messy Migrations"](http://www.informit.com/articles/article.aspx?p=1652025) – Claudio Floreani Jan 26 '17 at 16:37
  • but this doesn't seed the database, so don't forget to run `$ rails db:seed` afterwards! – Salomanuel Jun 24 '19 at 08:06
47

I use the following one liner in Terminal.

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

I put this as a shell alias and named it remigrate

By now, you can easily "chain" Rails tasks:

$ 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+
Sebastián Palma
  • 32,692
  • 6
  • 40
  • 59
TK.
  • 27,073
  • 20
  • 64
  • 72
  • 12
    That's going to run all of your migrations one after the other, which isn't scalable and is error-prone. Also, I'm pretty sure db:migrate updates your schema.rb, so your schema:dump isn't doing anything useful. – coreyward Nov 07 '10 at 01:36
  • so how does one empty the database? in development... clear it all out. – AnApprentice Nov 07 '10 at 01:39
  • 3
    @AnApprentice You can run `db:reset`, which is just a Google (or check on the [Guides](http://guides.rubyonrails.org)) away. My comment wasn't to advise against using that, but to avoid using `db:migrate` when what you really want is `db:schema:load`. – coreyward Dec 10 '12 at 23:54
  • 7
    By the way, @TK, you really don't need to run all of these as separate processes dependent on the exit status of the last. Instead, just pass all desired tasks to `rake`, like so: `rake db:drop db:create db:schema:load`. – coreyward Dec 10 '12 at 23:55
  • 1
    It's anecdotal, but I've never had an issue running `db:migrate`... whereas `db:schema:load` is sensitive to someone forgetting to check schema.rb into version control alongside a new migration. – johncip Feb 02 '16 at 08:23
43

Update: In Rails 5, this command will be accessible through this command:

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


As of the newest rails 4.2 release you can now run:

rake db:purge 

Source: 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

It can be used together like mentioned above:

rake db:purge db:create db:migrate RAILS_ENV=test
NM Pennypacker
  • 6,704
  • 11
  • 36
  • 38
Robbie Guilfoyle
  • 3,363
  • 1
  • 18
  • 18
30

Depending on what you're wanting, you can use…

rake db:create

…to build the database from scratch from config/database.yml, or…

rake db:schema:load

…to build the database from scratch from your schema.rb file.

coreyward
  • 77,547
  • 20
  • 137
  • 166
  • 1
    You've got to drop the database first…or you can just delete the tables if you prefer. – coreyward Nov 07 '10 at 01:34
  • 5
    +1 for schema load. sometimes migrations get messed up, but the schema should be what is kept intact. – Danny Oct 28 '11 at 19:58
  • I read in The Rails 3 Way that loading the schema is the way to go, as opposed to running all the migrations. I don't remember exactly what their reasoning was but it seems to make sense. If the end result is the same either way, it seems simpler and less error-prone just to load the database from the schema than to run a bunch of migrations. – Jason Swett Aug 03 '12 at 19:48
  • 4
    The reasoning is that migrations are meant to *migrate* data, and become increasingly brittle over time as your models change. You can (and should) bake in bare-minimum scoped models into your migrations whenever feasible to ensure they run, but this just doesn't scale well and is much less efficient than just building the database from what the application knows is the final point. Why rely on migrations to create a database that looks like your schema when you can just build from the blueprint itself? – coreyward Aug 03 '12 at 19:57
18

From the command line run

rake db:migrate:reset
eebbesen
  • 5,070
  • 8
  • 48
  • 70
user2747051
  • 181
  • 1
  • 2
  • 2
    this is the only way that makes the app to run all migrations again. Because each migration makes changes to `schema.rb` and if you only `drop` and `create`, `migrate` will do nothing (tested on rails 6) – shampoo May 05 '20 at 18:06
15

In Rails 6 there is a convenient way for resetting DB and planting seeds again:

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/

Mario Pérez Alarcón
  • 3,468
  • 2
  • 27
  • 38
13

Use like

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

All in one line. This is faster since the environment doesn't get reloaded again and again.

db:drop - will drop database.

db:create - will create database (host/db/password will be taken from config/database.yml)

db:migrate - will run existing migrations from directory (db/migration/.rb)*.

db:seed - will run seed data possible from directory (db/migration/seed.rb)..

I usually prefer:

rake db:reset

to do all at once.

Cheers!

Manish Shrivastava
  • 30,617
  • 13
  • 97
  • 101
  • 1
    I like to add db:test:prepare to this, for good measure. This depends, of course, on whether or not you're testing. – ctc Apr 21 '15 at 19:49
  • 1
    `db:reset == db:drop + db:schema:load + db:seed`, `db:migrate:reset == db:drop + db:create + db:migrate` – x-yuri Jun 06 '18 at 20:05
11

Just issue the sequence of the steps: drop the database, then re-create it again, migrate data, and if you have seeds, sow the database:

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

Since the default environment for rake is development, in case if you see the exception in spec tests, you should re-create db for the test environment as follows:

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

In most cases the test database is being sowed during the test procedures, so db:seed task action isn't required to be passed. Otherwise, you shall to prepare the database:

rake db:test:prepare

or

RAILS_ENV=test rake db:seed

Additionally, to use the recreate task you can add into Rakefile the following code:

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

Then issue:

rake db:recreate
Малъ Скрылевъ
  • 16,187
  • 5
  • 56
  • 69
8

You can manually do:

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

Or just rake db:reset, which will run the above steps but will also run your db/seeds.rb file.

An added nuance is that rake db:reset loads directly from your schema.rb file as opposed to running all the migrations files again.

You data gets blown away in all cases.

Erik Trautman
  • 5,883
  • 2
  • 27
  • 35
6

You can use this following command line:

rake db:drop db:create db:migrate db:seed db:test:clone
Pawel
  • 407
  • 1
  • 6
  • 14
user1358180
  • 371
  • 3
  • 5
4

To drop a particular database, you can do this on rails console:

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

And then migrate DB again

$bundle exec rake db:migrate 
Kush
  • 909
  • 1
  • 8
  • 14
4

On rails 4.2, to remove all data but preserve the database

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

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

Yana Agun Siswanto
  • 1,932
  • 18
  • 30
  • Well... Just tried it, but it does not preserve tables and columns. You have to run a db:migrate after having run a db:purge. So this does not preserve tables and columns. It does however preserve the database itself so you do not have to db:create – Freddo Mar 23 '16 at 14:23
  • 1
    @Cedric You are right, db:purge is not preserve the table. I updated the code. – Yana Agun Siswanto Apr 06 '16 at 13:19
3

You can use db:reset - for run db:drop and db:setup or db:migrate:reset - which runs db:drop, db:create and db:migrate.

dependent at you want to use exist schema.rb

3

3 options, same result:

1. All steps:

  $ 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. Reset:

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

3. Migrate:reset:

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

Notes:

  • If schema:load is used is faster than doing all migrations, but same result.
  • All data will be lost.
  • You can run multiple rakes in one line.
  • Works with rails 3.
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
urko
  • 41
  • 5
2

According to Rails guide, this one liner should be used because it would load from the schema.rb instead of reloading the migration files one by one:

rake db:reset
Victor
  • 13,010
  • 18
  • 83
  • 146
2

Because in development , you will always want to recreate the database,you can define a rake task in your lib/tasks folder like that.

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

and in terminal you will run

rake db:all

it will rebuild your database

Obed Lorisson
  • 449
  • 3
  • 8
  • 22
1

I think the best way to run this command:

**rake db:reset** it does db:drop, db:setup
 rake db:setup does db:create, db:schema:load, db:seed
Thorin
  • 2,004
  • 1
  • 19
  • 30
1

Simply you can run

rake db:setup

It will drop database, create new database and populate db from seed if you created seed file with some data.

Touseef Murtaza
  • 1,548
  • 14
  • 20
1

I use:

  • rails db:drop to delete the databases.
  • rails db:create to create the databases based on config/database.yml

The previous commands may be replaced with rails db:reset.

Don't forget to run rails db:migrate to run the migrations.

0

I've today made quite a few changes to my rails schema. I realised I needed an additional two models in a hierarchy and some others to be deleted. There were many little changes required to the models and controllers.

I added the two new models and created them, using:

rake db:migrate

Then I edited the schema.rb file. I manually removed the old models that were no longer required, changed the foreign key field as required and just reordered it a bit to make it clearer to me. I deleted all the migrations, and then re-ran the build via:

rake db:reset

It worked perfectly. All the data has to be reloaded, of course. Rails realised the migrations had been deleted and reset the high-water mark:

-- assume_migrated_upto_version(20121026094813, ["/Users/sean/rails/f4/db/migrate"])
port5432
  • 5,889
  • 10
  • 60
  • 97
0

TL;DR - I use this rake script during development to blow away everything, including the schema file, then rebuild directly from migration scripts. It rebuilds both dev and test databases simultaneously. It's the only way I've found to guarantee everything lines up the way I expect. Been using it for years without a problem.

# lib/tasks/db_rebuild.rake

require 'fileutils'

namespace :db do
  desc "Create DB if it doesn't exist, then migrate and seed"
  task :build do
    Rake::Task["db:create"].invoke
    Rake::Task["db:migrate"].invoke
    Rake::Task["db:seed"].invoke
  end

  desc "Drop database and rebuild directly from migrations (ignores schema.rb)"
  task :rebuild do
    raise "Task not permitted in production." if ENV["RAILS_ENV"] == "production"

    puts "*** Deleting schema.rb"
    system "rm -f #{Rails.root.join("db", "schema.rb")}"

    puts "*** Deleting seed lock files"
    system "rm -f #{Rails.root.join("db", ".loaded*")}"

    puts "*** Recreate #{ENV['RAILS_ENV']} database"
    begin
      Rake::Task['environment'].invoke
      ActiveRecord::Base.connection
    rescue ActiveRecord::NoDatabaseError
      # database doesn't exist yet, just create it.
      Rake::Task["db:build"].invoke
    rescue Exception => e
      raise e
    else
      Rake::Task["db:environment:set"].invoke
      # https://github.com/rails/rails/issues/26319#issuecomment-244015760
      # ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"] = '1'
      Rake::Task["db:drop"].invoke
      Rake::Task["db:build"].invoke
    end
    Rake::Task["db:retest"].invoke
  end

  desc "Recreate the test DB"
  task :retest do
    system("rake db:drop db:build RAILS_ENV=test")
  end
end

Rationale - The problem with all the provided solutions is that native Rake tasks provided by Rails rely on schema.rb. When I am doing heavy data modeling, I make changes directly to the migration files; only after they've been committed upstream do we treat them as immutable. But if I make changes to the migration file, they aren't reflected in schema.rb.

The other problem is the distinction between dev and test environments. Rails db tasks handle them independently, but in my experience dev and test databases should always maintain parity, which means I had to run lots of duplicative database cleanup when developing.

Frank Koehl
  • 3,104
  • 2
  • 29
  • 37