« 12.04 久しぶりのVSに戸惑いを隠せず | ココ | 12.09 日本語キーボードを訪ねて三千里(xrdp 0.5 純情派) »

2009年12月 8日

Rakeタスク作りに勤しむ1日  このエントリーを含むはてなブックマーク 

CSVやらTSVのデータをまるごとDBにインポートさせてやろうと画策するのに、Rakeを使えばきれいになるなと思い立ち、これまでControllerでやってた処理とかを整理してた、そんな1日。リファクタリングは嫌いじゃないけど、あんまりやりすぎてもなー。まぁ、お陰でControllerでの処理で共通化できるところを外にはじき出せたんで、いいってことにしよう。

例えば、こんなの。

class CreateTaxonomies < ActiveRecord::Migration
  def self.up
    create_table(:taxonomies, :id => false) do |t|
      t.integer :id, :null => false
      t.integer :parent_id
      t.string :rank
      t.string :emblcode
      t.text :comment
    end

    add_index :taxonomies, :id, :unique => true
    add_index :taxonomies, :parent_id
  end

  def self.down
    drop_table :taxonomies
  end
end

class CreateTaxonomyaliases < ActiveRecord::Migration
  def self.up
    create_table(:taxonomyaliases, :id => false) do |t|
      t.integer :taxonomy_id
      t.string :name, :limit => 1024
      t.string :tag, :limit => 60
    end

    add_index :taxonomyaliases, :taxonomy_id
  end

  def self.down
    drop_table :taxonomyaliases
  end
end

というNCBI Taxonomyのテーブルを作って、$RAILS_ROOT/lib/tasks/load_data.rake というファイル↓を作ってやる。

require 'active_record'

namespace :db do
  namespace :import do

    desc 'Import taxonomy data'
    task :taxonomy => :environment do
      @d = File.join(File.dirname(__FILE__), 'init_data')

      def insert_into_aliases
        puts 'Import names.dmp'
        f = File.join(@d, 'names.dmp')
        open(f) { |ff|
          while l = ff.gets
            cols = l.split(/\t\|\t?/)
            next unless (cols.size > 0 && cols[0].size > 0)
            Taxonomyalias.find_or_initialize_by_taxonomy_id_and_name(
                cols[0].to_i, cols[1]) { |t|
              t.tag = cols[3]
              t.save
              print
            }
          end
        }
      end

      def insert_into_nodes
        puts 'Import nodes.dmp'
        f = File.join(@d, 'nodes.dmp')
        open(f) { |ff|
          while l = ff.gets
            cols = l.split(/\t\|\t?/)
            next unless (cols.size > 0 && cols[0].size > 0)
            Taxonomy.find_or_initialize_by_id(cols[0].to_i) { |t|
              t.parent_id = cols[1]
              t.rank = cols[2]
              t.emblcode = cols[3]
              t.comment = cols[12]
              t.save
              print
            }
          end
        }
      end

      insert_into_aliases
      insert_into_nodes
    end
  end
end

$RAILS_ROOT/lib/tasks/init_data に、FTPでとってきたTaxonomyのデータに含まれるnames.dmpとnodes.dmpを入れておけば、rake db:import:taxonomy でテーブルにどんどんデータを入れてくれるとか。

$ rake --tasks
(in /home/xxxx/NetBeansProjects/project1)
rake db:import:taxonomy # Import taxonomy data

とかこんな感じで出てくれるし。

実際は、Controllerから外に書き出したHelperの関数を呼び出したりしているので、Helperで呼び出してるLoggerをうまく動かすのにloggerと指定してたのをRails.loggerとクラスまで指定してやるようにしたり途中でAbortしないようにせんとあかんかったけど。

前にバッチ処理でどうしようかとか考えてたけど、rakeタスクのファイルを作るの思ったより難しくなかったな、こっちしとけばよかった…。

By ただ at 20:42 カテゴリー ; プログラミング単語帳 , プログラミングとか

« 12.04 久しぶりのVSに戸惑いを隠せず | 12月の記事 | 12.09 日本語キーボードを訪ねて三千里(xrdp 0.5 純情派) »




トラックバック

このエントリーのトラックバックURL:
http://pinmarch.sakura.ne.jp/mt/mt-tb.cgi/1514