<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>RealityForge.org: Dumping database to YAML fixtures</title>
    <link>/articles/2005/12/14/dumping-database-to-yaml-fixtures</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>A little short for a storm trooper</description>
    <item>
      <title>Dumping database to YAML fixtures</title>
      <description>&lt;p&gt;I finally got fed up with the bugs in Rails 1.0 handling of mysql connections and have decided to move to postgres. I have &lt;a href="http://www.realityforge.org/articles/2005/12/02/mysql_to_postgres"&gt;talked&lt;/a&gt; about the move and even migrated my &lt;span class="caps"&gt;DDL&lt;/span&gt; to the database agnostic &lt;a href="http://api.rubyonrails.com/classes/ActiveRecord/Schema.html"&gt;schema&lt;/a&gt; language. The one thing I had not yet thought about was how to move my data.&lt;/p&gt;


	&lt;p&gt;After doing a little bit of &lt;a href="http://www.mail-archive.com/typo-list@rubyforge.org/msg01274.html"&gt;asking&lt;/a&gt; and &lt;a href="http://comments.gmane.org/gmane.comp.lang.ruby.rails/28315"&gt;searching&lt;/a&gt; I decided to just dump my data out the databse to fixtures and then reload these fixtures. This is surprisingly simple using the rake task.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;desc&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Dump a database to yaml fixtures. &lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;task&lt;/span&gt; &lt;span class="symbol"&gt;:dump_fixtures&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:environment&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;path&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;ENV&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;FIXTURE_DIR&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{RAILS_ROOT}&lt;/span&gt;/data&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

  &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;establish_connection&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_sym&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connection&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;
             &lt;span class="ident"&gt;select_values&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;show tables&lt;/span&gt;&lt;span class="punct"&gt;').&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;table_name&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
    &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;open&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{path}&lt;/span&gt;/&lt;span class="expr"&gt;#{table_name}&lt;/span&gt;.yml&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;wb&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;file&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;file&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;write&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connection&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;
          &lt;span class="ident"&gt;select_all&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;SELECT * FROM &lt;span class="expr"&gt;#{table_name}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;inject&lt;/span&gt;&lt;span class="punct"&gt;({})&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;hash&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;record&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;hash&lt;/span&gt;&lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{table_name}&lt;/span&gt;_&lt;span class="expr"&gt;#{i += 1}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;record&lt;/span&gt;
        &lt;span class="ident"&gt;hash&lt;/span&gt;
      &lt;span class="punct"&gt;}.&lt;/span&gt;&lt;span class="ident"&gt;to_yaml&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;desc&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Reset Database data to that in fixtures that were dumped&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="ident"&gt;task&lt;/span&gt; &lt;span class="symbol"&gt;:load_dumped_fixtures&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:environment&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;active_record/fixtures&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;establish_connection&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_sym&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;path&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;ENV&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;FIXTURE_DIR&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{RAILS_ROOT}&lt;/span&gt;/data&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="constant"&gt;Dir&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;glob&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{path}&lt;/span&gt;/*.{yml}&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;fixture_file&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="constant"&gt;Fixtures&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;create_fixtures&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;basename&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;fixture_file&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;.*&lt;/span&gt;&lt;span class="punct"&gt;'))&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

This is Mysql specific due to the use of 
&lt;code&gt;select_values('show tables')&lt;/code&gt; but apparently sqlite usues &lt;code&gt;select_values('.table')&lt;/code&gt; and postgres uses the following. 

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_sql "&gt; select_values(&amp;lt;&amp;lt;-end_sql
SELECT c.relname
 FROM pg_class c
   LEFT JOIN pg_roles r     ON r.oid = c.relowner
   LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
 WHERE c.relkind IN ('r','')
   AND n.nspname IN ('myappschema', 'public')
   AND pg_table_is_visible(c.oid)
end_sql&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This worked like a charm except when my data contained embedded &lt;span class="caps"&gt;ERB&lt;/span&gt; directives because when rails loads the fixtures it attempts to evaluate the fixture as an &lt;span class="caps"&gt;ERB&lt;/span&gt; script. In this scenario I just needed to nip into the &lt;code&gt;read_fixture_files&lt;/code&gt; method in &lt;code&gt;$RUBY_HOME\activerecord-1.13.2\lib\active_record\fixtures.rb&lt;/code&gt;
and comment out the erb rendering while I imported my data.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; The code for this can be found is available in &lt;a href="/files/dump_fixtures.rake"&gt;dump_fixtures.rake&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 14 Dec 2005 13:28:00 +1100</pubDate>
      <guid isPermaLink="false">urn:uuid:5e0e20e3e1a62e4e9b1721d5a4d26b14</guid>
      <author>Peter Donald</author>
      <link>http://www.realityforge.org/articles/2005/12/14/dumping-database-to-yaml-fixtures</link>
      <category>Rails</category>
      <enclosure type="application/octet-stream" url="http://www.realityforge.org/files/dump_fixtures.rake" length="1077"/>
      <trackback:ping>http://www.realityforge.org/articles/trackback/11</trackback:ping>
    </item>
  </channel>
</rss>
