CSV ファイルをデータベースにロードRubyで処理
データベースのCLIでCSVからのロードコマンドは提供されているので、そのままなら、開発は不要。
データ加工などある場合に有効
- 歩数計データを、ウェルネスリンク機器専用 測定記録取り込みソフトウェアからCSVにエクスポート
- エデイタで読み込み、ヘッダー行は削除し漢字コードをutf8で保存
- 歩行距離などを集計し、平均値を読み込む
- ヘッダーない場合は、行のカラム配列のハッシュ配列とならず、添え字でカラム値を参照
require 'csv' require 'sqlite3' # sqlite3読み込み begin db = SQLite3::Database.new 'health.db' rescue SQLite3::SQLException => e puts "open database return: " puts "#{e}\n" end table_name = "walking" puts "$0:#{$0}" ARGV.each_with_index do |arg, i| puts "ARGV[#{i}]:#{arg}" csvfile = ARGV[i] csv_data = CSV.read(csvfile) sum = 0.0 cnt = 0 max = 0.0 min = 999.999 fromdate = nil todate = nil csv_data.each do |data| if fromdate == nil fromdate = data[0] end todate = data[0] intro_msg = "#{data[0]}の#{data[1]}歩数(歩)、#{data[4]}歩行距離(km)です。\n" if data[1] == nil puts 'no data ' + intro_msg next else sum = sum + data[4].to_f cnt = cnt + 1 if max < data[4].to_f max = data[4].to_f end if min > data[4].to_f && data[4].to_f > 0.0 min = data[4].to_f end # 各行 # 1 wdate text, /* 日付 */ # 2 steps integer, /* 歩数(歩) */ # 3 usteps integer, /* しっかり歩数(歩) */ # 4 exsteps integer, /* Ex歩数(歩) */ # 5 walkingdistance real, /* 歩行距離(km) */ # 6 walkingtime integer, /* 歩行時間(分) */ # 7 uwalkingtime integer, /* しっかり歩行時間(分) */ # 8 exquantity real, /* Ex量(Ex) */ # 9 calorie integer, /* 消費カロリー(kcal) */ # 10 fatvolume real, /* 脂肪燃焼量(g) */ # 11 pickupclass text, /* 取込分類 */ # 12 pickupdatetime text, /* 取込日時 */ # 13 equipmentname text, /* 機器名 */ # 14 serialno text, /* シリアル */ # 15 personalnumber text /* 個人番号 sql = "INSERT INTO " + table_name + " VALUES (" num_lines = 0 j = 0 data.each do |field| cell = field.to_s # 「,,,」のような行では、フィールド値が nil になる。そのときは NULL if ( field.nil? ) sql = sql + "NULL" elsif ( field.empty? ) # 元の CSV ファイルで,「空」になっているようなセル sql = sql + "NULL" elsif ( j == 0 || j >= 10 ) # 文字列属性のときは「'」で囲む. gsub を使い、文字列中の全ての「'」は「''」に置き換える(これは SQL の流儀) sql = sql + "'" + cell.gsub("'","''") + "'" elsif # 数値("INTEGER" または "REAL")のときは,文字列の先頭と末尾の空白文字を取り除く sql = sql + cell.strip end if ( j < (data.size - 1) ) # 最後のフィールドでないときは「,」で継続 sql = sql + ", " end j += 1 end # 最後は「);」で終わる sql = sql + ");" num_lines += 1 # 1000 行ごとにコミット if num_lines == 1000 db.execute("COMMIT;") puts "commit return\n" db.execute("BEGIN TRANSACTION;") puts "BEGIN TRANSACTION return\n" num_lines = 0 end begin db.execute(sql) rescue SQLite3::SQLException => e puts "#{sql} database return:}" puts "#{e}\n" end puts "record:#{cnt.to_s} #{sql} return\n}" end end db.close puts "database close return\n}" puts 'start:' + fromdate + ' to:' + todate + "\n" total_msg = "合計件数:#{cnt} 平均歩行距離(km):#{(sum/cnt).round(3)} MAX歩行距離(km):#{max} MIN歩行距離(km):#{min}\n" puts total_msg end