migrating legacy data

27
Patrick Crowley the.railsi.st

Upload: patrick-crowley

Post on 16-May-2015

929 views

Category:

Technology


1 download

DESCRIPTION

This talk describes a nice technique for migrating legacy data into a Rails app. Code samples are here: http://github.com/mokolabs/legacy/tree/master

TRANSCRIPT

Page 1: Migrating Legacy Data

Patrick Crowleythe.railsi.st

Page 2: Migrating Legacy Data

Migrating Legacy Data

Page 5: Migrating Legacy Data

How do you migrate your old data?

Page 6: Migrating Legacy Data
Page 7: Migrating Legacy Data

• Dump old database

Page 8: Migrating Legacy Data

• Dump old database

• Massage text with TextMate, BBEdit, grep, etc.

Page 9: Migrating Legacy Data

• Dump old database

• Massage text with TextMate, BBEdit, grep, etc.

• Eventually give up

Page 10: Migrating Legacy Data

• Dump old database

• Massage text with TextMate, BBEdit, grep, etc.

• Eventually give up

• Import into new database

Page 11: Migrating Legacy Data

Here’s a better way.

Page 12: Migrating Legacy Data

Step 1:Add new db adapter

Page 13: Migrating Legacy Data

development: adapter: mysql encoding: utf8 database: cinema_development username: root password:

...

legacy: adapter: mysql encoding: utf8 database: cinema_legacy username: root password:

/config/database.yml

Page 14: Migrating Legacy Data

Step 2:Add Legacy models

Page 15: Migrating Legacy Data

class LegacyBase < ActiveRecord::Base self.abstract_class = true establish_connection "legacy" def migrate new_record = eval("#{self.class}".gsub(/Legacy/,'')).new(map) new_record[:id] = self.id new_record.save end

end

/app/models/legacy_base.rb

Page 16: Migrating Legacy Data

class LegacyArchitect < LegacyBase set_table_name "architect"

def map { :first_name => self.name_first, :last_name => self.name_last, :description => self.desc_long } end

end

/app/models/legacy_architect.rb

Page 17: Migrating Legacy Data

Step 3:Add Migration helper

Page 18: Migrating Legacy Data

def migrate(name, options={}) # Grab custom entity label if present label = options.delete(:label) if options[:label] unless options[:helper] model = name.to_s.singularize.capitalize model.constantize.delete_all

puts "Migrating #{number_of_records || "all"} #{label || name} #{"after #{offset_for_records}" if offset_for_records}" "Legacy#{model}".constantize.find(:all, with(options)).each do |record| record.migrate end else eval options[:helper].to_s endend

def with(options={}) {:limit => number_of_records, :offset => offset_for_records}.merge(options)end

def number_of_records nil || ENV['limit'].to_i if ENV['limit'].to_i > 0end

def offset_for_records nil || ENV['offset'].to_i if ENV['offset'].to_i > 0end

/lib/migration_helper.rb

Page 19: Migrating Legacy Data

Step 4:Add Rake task

Page 20: Migrating Legacy Data

require 'migration_helper'

namespace :db do

namespace :migrate do desc 'Migrates legacy content' task :legacy => ["architects", "styles"] desc 'Migrates architects' task :architects => :environment do migrate :architects end desc 'Migrates theaters' task :theaters => :environment do migrate :theaters end endend

/lib/tasks/migrate.rake

Page 21: Migrating Legacy Data

Step 5:Start migrating

Page 22: Migrating Legacy Data

Demo

Page 24: Migrating Legacy Data

Special thanks

Page 25: Migrating Legacy Data

Questions?

Page 26: Migrating Legacy Data

The End

Page 27: Migrating Legacy Data