Skip to content

Instantly share code, notes, and snippets.

@vjt
Created January 28, 2009 10:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vjt/53882 to your computer and use it in GitHub Desktop.
Save vjt/53882 to your computer and use it in GitHub Desktop.
# Originally posted on http://pastie.org/25291 (1 December 2006)
# Transmigration between two different database configurations.
# Schema must be already in place. e.g: rake db:schema:load
# Licensed in the Public domain (or the DWTFYW License, at your
# option).
# -vjt@openssl.it
source:
adapter: mysql
host: antani.local
username: example
password: antani
dest:
adapter: postgresql
host: tapioca.local
username: example
password: tapioca
# -*- ruby, starfish -*-
#
# starfish: http://www.rufy.com/starfish/doc
#
# Single table only, this is not intended to copy the whole
# database. enhancements are welcome.
# The table to migrate must be passed via user environment.
#
# $ MIGRATE_TABLE=service_days starfish lib/starfish-transmigrate.rb &
# [1] 12748
# server started for .........
#
# once started the server, and a single client process, you can
# then launch as many subsequent client processes as you like.
#
# $ MIGRATE_TABLE=service_days starfish lib/starfish-transmigrate.rb &
# [2] 43783
# $ MIGRATE_TABLE=service_days starfish lib/starfish-transmigrate.rb &
# [3] 19234
# $ MIGRATE_TABLE=service_days starfish lib/starfish-transmigrate.rb &
# [4] 48923
#
# - vjt@openssl.it
require 'transmigrate'
raise "#{ARGV[0]}: table name missing!" unless table = ENV['MIGRATE_TABLE']
$klasses = Transmigrate.migration_classes table
server do |map_reduce|
map_reduce.type = $klasses[0]
map_reduce.limit = 5000
end
client do |source|
# yes, I know that this is not DRY. :)
#
o = $klasses[1].new(source.attributes)
o.id = source.id
o.save
end
## -*- ruby -*-
## Usage:
#
# $ script/console
# Loading development environment
# >> require 'transmigrate'
# true
# >> Transmigrate.classes.each &Transmigrate.proc
# processing ProductsSource -> ProductsDest
# [ ... ]
#
# - vjt@openssl.it
$conf = YAML::load File.open("config/migrate.yml")
class Transmigrate
class << self
def classes
ActiveRecord::Base.connection.tables.map do |table|
migration_classes table
end
end
def migration_classes(t)
%w|source dest|.map { |c|
klass = (t + '_' + c).camelize
eval %{
class ::#{klass} < ActiveRecord::Base
establish_connection $conf['#{c}']
set_table_name '#{t}'
end
}
klass.constantize
}
end
STEP = 500
def proc
Proc.new { |source, dest|
puts "processing #{source} -> #{dest}"
dest.silence {
dest.transaction {
source.connection.execute("SET character_set_results = 'utf8'");
(0..source.count).step(STEP) { |offset|
source.find(:all, :limit => STEP, :offset => offset).each { |item|
o = dest.new(item.attributes)
o.id = item.id
o.save
}
}
}
}
}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment