Is there any trivial way to copy the data from developmenet database into the test one? I know theres a way to copy schema and recreate database, but is there any rake task to populate test database with development one?
You can use mysql directly:
mysqldump app_development | mysql app_test
You can use:
rake db:test:clone
To copy the development db into test.
For all databases:
rake db:test:clone && rake db:seed RAILS_ENV='test'
With Postgres, copy the database like so:
CREATE DATABASE newdb WITH TEMPLATE originaldb OWNER dbuser;
If you just want to clone the development DB in its entirety, what's wrong with just copying the development.sqlite3 and renaming it test.sqlite3? You can automate the process by setting up a batch file (or its equivalent on your OS) that you can run from the command line.
This will work locally, but I just realized you might be thinking a non-local environment, in which case it probably won't.
An alternative method if you use seeds (db/seeds.rb)
First, add a rake task for example to lib/tasks/test_seed.rake with this code:
namespace :db do
namespace :test do
task :prepare => :environment do
Rake::Task["db:seed"].invoke
end
end
end
Then whenever you changed your database structure / content through migration and seeds, you can run
rake:db:test:prepare
To copy the schema and seed data.
So the complete steps would be:
rake db:migrate
rake db:seed
rake db:test:prepare
Related
I have stated working on neo4j with rails using the gem 'neo4j', I want to seed some data in neo4j database. But whenever I am trying to do rake db:seed, it says
rake aborted!
Don't know how to build task 'db:seed'
I have checked all the rake tasks using rake -T, and there is no rake db:seed.
Does any one have any idea?
The Neo4j gem doesn't have a seed command. The command you're trying to use is provided by ActiveRecord. We'd love to add this functionality in, though, and if you'd like to help, we'd gladly accept a PR and/or contribute to the process. For now, open up an issue at https://github.com/neo4jrb/neo4j/issues and we can add it to the roadmap.
Finally got the solutions.
Create a file seed.rake under lib/tasks and put the code
namespace :db do
desc 'Load the seed data from db/seeds.rb'
task :seed => :environment do
seed_file = File.join(Rails.root, 'db', 'seeds.rb')
load(seed_file) if File.exist?(seed_file)
end
end
Check apps root directory, is there a Rakefile?
Make a file with name "Rakefile" and enter these line
"#!/usr/bin/env rake
require File.expand_path('../config/application', FILE)
APP_NAME::Application.load_tasks
As others mentioned before, rails db:seed is a built-in feature backed by ActiveRecord. Assuming you are using neo4jrb without ActiveRecord, you won't be able to use this command to seed database any more.
However, you can use seedbank gem to recover this ability.
It does not depend on ActiveRecord like seed_fu and other seeding gems do. So it will work just fine with neo4jrb.
The process is rather simple.
put seedbank in your Gemfile and bundle install.
create directory db/seeds/
create a seeds file under the db/seeds/ directory
for example
#db/seeds/show.seeds.rb
Show.create(name: "Better Call Saul", producer: "Vince Gilligan")
run rake db:seed:show
I'm using rails 2.3, and I've generated a development_structure.sql using
rake db:test:clone_structure
How do I import this into my test database? Is there a rails 2.3 compatible rake task for it?
I'm using development_structure.sql as a reference for the structure of my database (and not migrations) that I add to my repo, so I want an easy way to test different database structures as the database changes.
I think you can use
rake db:structure:dump RAILS_ENV=test
UPDATE: I don't know what's wrong with me today. You should use
rake db:setup RAILS_ENV=test
If I remember correctly, that will use structure.sql if you have the schema_format set to sql
Try this:
> rake db:test:prepare
Database mydb_test loaded from db/development_structure.sql.
Maybe you want to transform this .sql into fixtures? The database is recreated every time you do a rake test
I am using Ruby on Rails 3.0.9 and I would like to seed the production database in order to add some record without re-building all the database (that is, without delete all existing records but just adding some of those not existing yet). I would like to do that because the new data is needed to make the application to work.
So, since I am using the Capistrano gem, I run the cap -T command in the console in order to list all available commands and to know how I can accomplish what I aim:
$ cap -T
=> ...
=> cap deploy:seed # Reload the database with seed data.
=> ...
I am not sure on the word "Reload" present in the "Reload the database with seed data." sentence. So, my question is: if I run the cap deploy:seed command in the console on my local machine will the seeding process delete all existing data in the production database and then populate it or will that command just add the new data in that database as I aim to do?
If you are using bundler, then the capistrano task should be:
namespace :deploy do
desc "reload the database with seed data"
task :seed do
run "cd #{current_path}; bundle exec rake db:seed RAILS_ENV=#{rails_env}"
end
end
and it might be placed in a separate file, such as lib/deploy/seed.rb and included in your deploy.rb file using following command:
load 'lib/deploy/seed'
This worked for me:
task :seed do
puts "\n=== Seeding Database ===\n"
on primary :db do
within current_path do
with rails_env: fetch(:stage) do
execute :rake, 'db:seed'
end
end
end
end
capistrano 3, Rails 4
Using Capistrano 3, Rails 4, and SeedMigrations, I created a Capistrano seed.rb task under /lib/capistrano/tasks:
namespace :deploy do
desc 'Runs rake db:seed for SeedMigrations data'
task :seed => [:set_rails_env] do
on primary fetch(:migration_role) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :rake, "db:seed"
end
end
end
end
after 'deploy:migrate', 'deploy:seed'
end
My seed migrations are now completely separate from my schema migrations, and ran following the db:migrate process. What a joy! :)
Try adding something like this in your deploy.rb:
namespace :deploy do
desc "reload the database with seed data"
task :seed do
run "cd #{current_path}; rake db:seed RAILS_ENV=#{rails_env}"
end
end
cap deploy:seed should basically be a reference to rake db:seed. It should not delete existing data, unless you specified it to do so in your seed.rb.
Best assumption for the word "Reload" is that :seed is a stateless command, I does not automatically know where it left off, like regular rails migrations. So technically you would always be "reloading" the seed, every time you run it. ...A wild guess, but it sounds good, no?
Please view Javier Vidal answer below
After a discussion with capistrano-rails gem authors I decided to implement this kind of tasks in a separate gem. I think this helps to follow the DRY idea and not implementing the same task over and over again.
I hope it helps you: https://github.com/dei79/capistrano-rails-collection
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?
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.
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.
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+
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
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.
From the command line run
rake db:migrate:reset
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/
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!
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
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.
You can use this following command line:
rake db:drop db:create db:migrate db:seed db:test:clone
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
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
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
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
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
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.
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
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.
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.
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"])
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.
To avoid an accidental 'rake db:reset' on our production environments, I was thinking about disabling 'rake db:reset' and related tasks that drop the database in the production environment. Is there an easy way to do this, or do I have to redefine the rake task?
Is there a better alternative?
In your Rake file you can add
Rake.application.instance_variable_get('#tasks').delete('db:reset')
and the command is not available any more. If you want to disable multiple commands, put it in a remove_task method for readability.
But a better alternative seem to just not type the rake db:reset command, which is not something you'd accidentally type.
Having a nice backup of your (production) database is also a better solution I suppose.
Put this in lib/tasks/db.rake:
if Rails.env == 'production'
tasks = Rake.application.instance_variable_get '#tasks'
tasks.delete 'db:reset'
tasks.delete 'db:drop'
namespace :db do
desc 'db:reset not available in this environment'
task :reset do
puts 'db:reset has been disabled'
end
desc 'db:drop not available in this environment'
task :drop do
puts 'db:drop has been disabled'
end
end
end
Found here.
Append this on your Rakefile.
namespace :db do
task :drop => :abort_on_production
end
task :abort_on_production do
abort "Don't drop production database. aborted. " if Rails.env.production?
end
It also blocks rake db:reset and rake db:migrate:reset because they call db:drop
You could always overwrite the db:reset task with something like this in lib/db.rake:
namespace :db do
desc 'Resets your database using your migrations for the current environment'
task :reset do
if RAILS_ENV == 'production'
Rake::Task["db:drop"].invoke
Rake::Task["db:create"].invoke
Rake::Task["db:migrate"].invoke
end
end
end
For the record, We have an application linking into our live production database, we use test login details and from there shard's to out test DB.
The last thing we wanted was for rails to wipe out or database schema when running rspec/unit tests.
use the information is this question and here: Is it possible to get a list of all available rake tasks in a namespace?
I was able to come up with the following solution:
Rake.application.in_namespace(:db){|x|
x.tasks.map{|t|
Rake.application.instance_variable_get('#tasks').delete(t.name)
}
}
This placed into the end of our Rakefile enabled us to remove all db: rake tasks as can be seen here:
[davidc#david-macbookp app1{master}]$ rake -T db
[davidc#david-macbookp app1{master}]$
With a little tweaking this could be done to disable on a per environment basis
Update:
Word of warning doing this for db namespace broke testunit and was required to add the addison:
namespace :db do
task 'test:prepare' do
end
end
You could also use the rails_db_protect gem.
You just add the gem and it automatically prevents you from running the following dangerous tasks in production:
db:setup db:reset db:drop db:create db:schema:load
If you have a production environment, like a staging environment, where you want to be able to run these tasks, you can configure the environment to allow it:
ENV['ALLOW_DANGEROUS_TASKS'] = 'true'
There is also the gem rails-safe-tasks which allows more configuration but does not appear to have any tests supporting it.