views:

1120

answers:

2

Hi, 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?

A: 

To create the new database use rake db:create, also if db:migrate is working already for you, then there isn't really a reason to change to db:schema:load. db:schema:load is a faster, but unless you are running thousands of migrations the actual wall clock time difference is minimal.

Mike Buckbee
If you're doing anything other than add/remove columns (for instance moving and changing data from one column to another), then your SELECT queries will break when they use model code that assumes different columns (e.g. 'ORDER BY ...'). That is the reason to use db:schema:load unless you're updating an existing database.
Andres Jaan Tack
+6  A: 

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
Andres Jaan Tack