Nuclear Rooster

20Dec/060

Migrating from a live database in Rails

There is a lot of hype about Rails migrations around, and it is well deserved, but I haven't really seen anything about using Migrations to migrate from an existing database. After messing about with CSV's and MySQL command line I found a much better way.

  1. Generate a model to wrap your old data. From your Rails app,
    script/generate model OldMember

    oughtta do it.

  2. Override the connection setting and table name for that new class. If you can connect to the old database all the better, or you can use mysqldump to dump the SQL and re-create it on a database you can access.
    class OldMember < ActiveRecord::Base
    set_table_name "MemberTable"
    end
    OldMember.establish_connection(:adapter => "mysql",
    :host => "localhost",
    :database => "WebApp2000",
    :username => "user",
    :password => "password")
  3. Create a migration,
    script/generate migration MoveOldMembers
  4. Write the migration using ruby! You can be flexible about migrating from something sloppy to a pretty rails ish schema. You can 1) move over fields, 2) move "Yes"/"No" style booleans to 1/0 style booleans, and you can create new Objects from bad database schema. Notice to methods, save!, which throws an error instead of returning false, and save_with_validation(false) if you don't care about end-user validation while your are migrating.
    class MoveOldMembers < ActiveRecord::Migration
    def self.up
    @old_members = OldMember.find(:all)
    @old_members.each do |old_member|
    
    new_member = Renter.new
    new_member.first_name = old_member.firstName unless old_member.firstName.nil?
    
    new_member.paid_renter_deposit = '1' if old_member.depositPaid == 'Yes'
    
    #Do not validate
    new_member.save_with_validation(false)
    
    if old_member.waivers.include? "General COC"
    waiver = Waiver.find(:first, :conditions => "name = 'General Liability' AND account_id=" + new_member.account_id.to_s)
    Waiverlist.new(:waiver_id => waiver.id,
    :renter_id=>new_member.id,
    :account_id => new_member.account_id).save!
    end
    
    end
    end
    
    def self.down
    Renter.destroy(:all)
    WaiverList.destroy(:all)
    Category.destroy(:all)
    Waiver.destroy(:all)
    end
    
    end
  5. Then,
     rake db:migrate

    and you are done

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment


No trackbacks yet.