Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Ruby database migration gem, that helps you move content from an old structure to a new structure?

Are there any Ruby gems/libraries that help you migrate from an old DB structure to a new structure? ActiveRecord migrations do a good job keeping track of a new db structure, but I wonder if there's something that helps you migrate an entire legacy db to a new structure:

transfer_from(:source_table => 'person', :destination_table => 'dudes_and_dudets') do

  from :name, :to => :full_name

  from :dob, :to => :age do |dob|    # this would, for example, load the result  
    (Date.today - dob)/60/60/24/365  # of the block into :age
  end

end

(I realize you could do these transforms just as easily with AR, but I'm hoping the magic library would have many more transforms.

Berns

like image 290
btelles Avatar asked Feb 16 '10 04:02

btelles


People also ask

What does migration do in Ruby?

Migrations are a convenient way to alter your database schema over time in a consistent way. They use a Ruby DSL so that you don't have to write SQL by hand, allowing your schema and changes to be database independent. You can think of each migration as being a new 'version' of the database.

What does rake db migrate do?

A migration means that you move from the current version to a newer version (as is said in the first answer). Using rake db:migrate you can apply any new changes to your schema. But if you want to rollback to a previous migration you can use rake db:rollback to nullify your new changes if they are incorrectly defined.

What can rails migration do?

A Rails migration is a tool for changing an application's database schema. Instead of managing SQL scripts, you define database changes in a domain-specific language (DSL). The code is database-independent, so you can easily move your app to a new platform.

How do I migrate a specific migration in rails?

To run a specific migration up or down, use db:migrate:up or db:migrate:down . The version number in the above commands is the numeric prefix in the migration's filename. For example, to migrate to the migration 20160515085959_add_name_to_users. rb , you would use 20160515085959 as the version number.


2 Answers

I've begun working on this.

If anyone would like to give tips on a better/more idiomatic, or more efficient implementation, please let me know.

http://github.com/btelles/legacy_migrations

edit:

I now have this exact syntax working on the above github repository... plan to add a few rake tasks for mapping the old structure to new ActiveRecord classes, and more transforms...in case anyone's interested.

It's also on gemcutter/rubygems: gem install legacy_migrations

like image 129
btelles Avatar answered Oct 02 '22 23:10

btelles


You can access all your models from within a migration, and thus handle all your data migrations right there too. If you already knew this, and your question was about a neater way of doing it, then of course this is not the answer you're looking for.

One problem with your example is that you can't migrate down to an earlier version, but only because of the block feature you demonstrate in conversions.

I admit that your example is nice and terse, but here's a regular migration example any way:

class FooBar < ActiveRecord::Migration
  def self.up
    # This is only needed if the new table will have the same name.
    # Move the old one aside.
    rename_table :users, :old_users

    # The new table structure
    create_table :users do |t|
      t.string :full_name
      t.date   :age
    end

    # Data migration
    OldUsers.all.each do |orig|
      User.create!(
        :full_name => orig.name,
        :age => (Date.today - orig.dob)/60/60/24/365
      )
    end

    # Clean up
    drop_table :old_users
  end

  def self.down
    # Exercise for the reader!
  end
end

# Temporary class for accessing the old table during conversion
class OldUsers < ActiveRecord::Base; end
like image 26
Stéphan Kochen Avatar answered Oct 02 '22 23:10

Stéphan Kochen