Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

db:schema:load vs db:migrate with capistrano

Tags:

I have a rails app that I'm moving to another server and I figure I should use db:schema:load to create the mysql database because it's recommended. My problem is that I'm using capistrano to deploy and it seems to be defaulting to rake db:migrate instead. Is there a way to change this or is capistrano using db:migrate for a good reason?

like image 375
Anon Avatar asked Aug 25 '09 17:08

Anon


People also ask

What does schema load do?

So schema:load takes the currently configured schema, derives the associated queries to match, and runs them all in one go. It's kind of a one-and-done situation. As you've seen, migrations make changes step-by-step.

What does rake db schema load do?

Unlike rake db:migrate that runs migrations that have not run yet, rake db:schema:load loads the schema that is already generated in db/schema. rb into the database. Always use this command when: You run the application for the first time.

What does DB Migrate do?

DB migration is moving data from one or more source platforms to another target database. There are several reasons for migrating from one database to another. For example, a business might want to save resources by switching to a cloud-based database.

What is schema RB?

The schema. rb serves mainly two purposes: It documents the final current state of the database schema. Often, especially when you have more than a couple of migrations, it's hard to deduce the schema just from the migrations alone. With a present schema.


2 Answers

Why to use db:schema:load

I find that my own migrations eventually do some shuffling of data (suppose I combine first_name and last_name columns into a full_name column, for instance). As soon as I do any of this, I start using ActiveRecord to sift through database records, and your models eventually make assumptions about certain columns. My "Person" table, for instance, was later given a "position" column by which people are sorted. Earlier migrations now fail to select data, because the "position" column doesn't exist yet.

How to change the default behavior in Capistrano

In conclusion, I believe deploy:cold should use db:schema:load instead of db:migrate. I solved this problem by changing the middle step which Capistrano performs on a cold deploy. For Capistrano v2.5.9, the default task in the library code looks like this.

namespace :deploy do   ...   task :cold do     update     migrate  # This step performs `rake db:migrate`.     start   end   ... end 

I overrode the task in my deploy.rb as follows.

namespace :deploy do   task :cold do       # Overriding the default deploy:cold     update     load_schema       # My own step, replacing migrations.     start   end    task :load_schema, :roles => :app do     run "cd #{current_path}; rake db:schema:load"   end end 
like image 111
Andres Jaan Tack Avatar answered Sep 28 '22 11:09

Andres Jaan Tack


Climbing up on the shoulders of Andres Jaan Tack, Adam Spiers, and Kamiel Wanrooij, I've built the following task to overwrite deploy:cold.

task :cold do   transaction do     update     setup_db  #replacing migrate in original     start   end end  task :setup_db, :roles => :app do   raise RuntimeError.new('db:setup aborted!') unless Capistrano::CLI.ui.ask("About to `rake db:setup`. Are you sure to wipe the entire database (anything other than 'yes' aborts):") == 'yes'   run "cd #{current_path}; bundle exec rake db:setup RAILS_ENV=#{rails_env}" end 

My enhancements here are...

  • wrap it in transaction do, so that Capistrano will do a proper rollback after aborting.
  • doing db:setup instead of db:schema:load, so that if the database doesn't already exist, it will be created before loading the schema.
like image 24
Jon Garvin Avatar answered Sep 28 '22 09:09

Jon Garvin