開発者間でDBデータを共有するためのRakeタスク
- 仕様
- 動機
ペアプロで開発中に実装者を交代したところ、開発しながら適宜用意してきたデータの受け渡しに困ってしまいました。ここでは、各開発者はローカルに自分用のDBを持っているとします。開発しながら自由にデータを弄っています。スキーマの同期は migrate で対応していますが、データ自体は migrate には記述していません。
fixture あたりを上手に使えないかと探してみると「Railsレシピ」によさげなものを発見しました。これを利用して日本語の文字化け問題を解決した状態でDBからのデータ抽出ができましたが、 fixtureをすべて上書きしてしまうのはあまりに忍びない...抽出したデータを元に fixtureを作成するのが正しい気がします。楽だし。 (^^;
なので、別フォルダにデータを YAML形式で抽出して、必要であればDBにロードできるような Rakeタスクを作成してみました。
- 使い方
べちっと。
rake db:data:dump
YAML形式で抽出されたデータを、開発者間で共有。どうやって共有するかはとりあえず置いておく。ファイル共有?バージョン管理システム??
共有された側が、
rake db:data:load
相手のデータをそっくりそのままロードできます。ただし、rake db:migrate でスキーマの同期をあらかじめ取っておく必要があります。
- ソース
- share_data.rake
require 'yaml/encoding' class String alias :old_to_yaml :to_yaml def to_yaml(ops = {}) YAML.escape(self).old_to_yaml(ops) end end require "yaml" class String def is_binary_data? false end def decode gsub(/\\x(\w{2})/){[Regexp.last_match.captures.first.to_i(16)].pack("C")} end end ObjectSpace.each_object(Class){|klass| klass.class_eval{ if method_defined?(:to_yaml) && !method_defined?(:to_yaml_with_decode) def to_yaml_with_decode(*args) result = to_yaml_without_decode(*args) if result.kind_of? String result.decode else result end end alias_method :to_yaml_without_decode, :to_yaml alias_method :to_yaml, :to_yaml_with_decode end } } namespace :db do namespace :data do desc "dump data from database for sharing among developers" task :dump => :environment do sql = "SELECT * from %s order by id" skip_tables = ["schema_info"] ActiveRecord::Base.establish_connection (ActiveRecord::Base.connection.tables - skip_tables).each do |table_name| i = "000" FileUtils.mkdir_p("#{RAILS_ROOT}/db/data") File.open("#{RAILS_ROOT}/db/data/#{table_name}.yml", 'w') do |file| data = ActiveRecord::Base.connection.select_all(sql % table_name) file.write data.inject({}) { |hash, record| hash["#{table_name}_#{i.succ!}"] = record hash }.to_yaml() end end end desc "load data to database for sharing among developers" task :load => :environment do require 'active_record/fixtures' ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym) (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'db', 'data', '*.{yml,csv}'))).each do |fixture_file| Fixtures.create_fixtures('db/data', File.basename(fixture_file, '.*')) end end end end
- 作者: Chad Fowler,長瀬嘉秀,永田渉,株式会社テクノロジックアート
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2006/12/19
- メディア: 大型本
- 購入: 2人 クリック: 37回
- この商品を含むブログ (37件) を見る