<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Cristi Prodan's blog</title>
    <description></description>
    <link>http://cristiprodan.com/?feed=rss2</link>
    <item>
      <title>A DSL for "migrating" content between databases with different schemas</title>
      <link>&lt;a href="/2010/7/28/A_DSL_for_migrating_content_between_databases_with_different_schemas"&gt;A DSL for "migrating" content between databases with different schemas&lt;/a&gt;</link>
      <description>&lt;div class="entry"&gt;
        &lt;p&gt;
          &lt;span style="big-letter"&gt;T&lt;/span&gt;here were several occasions when I had to migrate the contents of a database into another database
          having a different schema. This happened especially when dealing with legacy databases.
        &lt;/p&gt;
        
        &lt;p&gt;  
          I usually write a script which "maps" fields from one database to another when dealing with this kind of situation. Recently, I thought 
          it would be a better idea to create a DLS where one would specify the mappings in a simpler way. So I started working on a gem 
          that does this. Here is how the gem can be used for migrating the contents of a database to another. 
        &lt;/p&gt;
        
        First, the super_migration gem needs to be installed:
        
        &lt;div class="source"&gt;&lt;pre&gt;
  &lt;span class="n"&gt;gem install super_migration&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
        
        Create a new ruby file &lt;span class="n"&gt;migrate.rb&lt;/span&gt;, where you would handle the migration rules and add the following content. The 
        &lt;span class="n"&gt;from_database&lt;/span&gt; call sets the  details for connection to the source database and &lt;span class="n"&gt;to_database&lt;/span&gt;, the details for the destination database. Since the gem uses
        ActiveRecord, they are the same as in the database.yml file inside a rails application. 
        
        &lt;p&gt;
          &lt;/p&gt;
&lt;div class="source"&gt;&lt;pre&gt;
  &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'super_migration'&lt;/span&gt; 
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;SM&lt;/span&gt; 

  &lt;span class="no"&gt;SuperMigration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; 
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_database&lt;/span&gt; &lt;span class="ss"&gt;:database&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"sm1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                       &lt;span class="ss"&gt;:adapter&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"mysql"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                       &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                       &lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"root"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                       &lt;span class="ss"&gt;:password&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; 

    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_database&lt;/span&gt; &lt;span class="ss"&gt;:database&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"sm2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                     &lt;span class="ss"&gt;:adapter&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"mysql"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                     &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                     &lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"root"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                     &lt;span class="ss"&gt;:password&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; 
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;

        
        
        Then using a simple DSL we can specify the field mappings as in the following example:

        &lt;p&gt;
          &lt;/p&gt;
&lt;div class="source"&gt;&lt;pre&gt;
  &lt;span class="no"&gt;SuperMigration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="ss"&gt;:from&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:books&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:to&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:livres&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;

      &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:from&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:to&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:autheur&lt;/span&gt;

      &lt;span class="c1"&gt;# apply a transformation to dob field&lt;/span&gt;
      &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:from&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="ss"&gt;:to&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:titre&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
        
        
        
        &lt;p&gt;Then the file needs to be ran and the script will take care of the migration: &lt;/p&gt;
        
        &lt;div class="source"&gt;&lt;pre&gt;
  &lt;span class="n"&gt;ruby migrate.rb&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;

        &lt;p&gt;I plan to further enhance this gem so that it supports more options and transformations. &lt;/p&gt;
    &lt;/div&gt;</description>
      <pubDate>Wed, 28 Jul 2010 01:21:59 -0700</pubDate>
      <guid>http://cristiprodan.com/posts/1</guid>
    </item>
  </channel>
</rss>
