Created
December 13, 2010 08:28
-
-
Save noqisofon/738795 to your computer and use it in GitHub Desktop.
tsv ファイルのデータを sqlite3 データベースファイルに変換する Ruby スクリプト。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!c:/bin/ruby/bin/ruby | |
# -*- encoding: cp932 -*- | |
# file: tsv2sqlite3.rb | |
require 'optparse' | |
require 'rubygems' | |
require 'sqlite3' | |
opt = OptionParser.new | |
OPTS = {} | |
opt.version = "0.0.1" | |
# | |
# -o <database_name> | |
# --output=<database_name> | |
# tsv ファイルの内容を格納するための sqlite3 データベースファイル名を指定します。 | |
# 既にあるデータベースファイルでも大丈夫です((同じテーブルがなければ…))。 | |
# 省略することもできます。この場合は、tsv ファイルのベースファイル名に拡張子 db を付けた名前にします。 | |
# | |
opt.on( "-o DATABASE", "--output=DATABASE", "sqlite3 データベースファイル名を指定します。" ) do |database_name| | |
OPTS[:output] = database_name | |
end | |
# | |
# -i <tsv_filepath> | |
# --input=<tsv_filepath> | |
# sqlite3 データベースファイルに格納する、タブ区切りデータファイルの場所を指定します。 | |
# もちろん省略できません。 | |
# 1 行目に列名が入っていることを前提にしています。 | |
# | |
opt.on( "-i TSVFILE", "--input=TSVFILE", "tsv ファイルの場所を指定します。" ) do |tsv_filepath| | |
OPTS[:input] = tsv_filepath | |
end | |
# | |
# --schema=<scheme_filepath> | |
# テーブルのスキーマクエリファイルの場所を指定します。 | |
# 省略可能ですが、その場合、列の型が全て text になってしまうかもしれません。 | |
# | |
opt.on( "--schema=SCHEMAFILE", "テーブルのスキーマクエリファイルの場所を指定します。" ) do |schema_filepath| | |
OPTS[:schema] = schema_filepath | |
end | |
# | |
# 指定された tsv ファイル名から、create table 文クエリを生成して返します。 | |
# | |
# この tsv ファイル名は、1 行目に列名が入っていることを前提にしています。 | |
# | |
def generate_create_table_query(filename) | |
rows = File.open( filename, "r:shift_jis" ) { |output| | |
output.each_line.to_a | |
}.map { |line| line.chomp! } | |
i = 0 | |
column_bodys = [] | |
cols = rows.shift.split( /\t/ ) | |
cols.each do |col| | |
if col =~ /.*_id/ || col =~ /.*_seq/ || col =~ /.*_enable/ then | |
type = "int" | |
else | |
type = "text" | |
end | |
if i == 0 | |
column_bodys << " #{col} #{type} primary key" | |
else | |
column_bodys << " #{col} #{type}" | |
end | |
i += 1 | |
end | |
return "create table #{File.basename(filename, '.*')} (#{column_bodys.join( ',' )})" | |
end | |
begin | |
opt.parse!( ARGV ) | |
if OPTS.has_key? :input then | |
input_file = OPTS[:input] | |
else | |
raise "no input file" | |
end | |
if OPTS.has_key? :output then | |
output_file = OPTS[:output] | |
else | |
output_file = "#{File.basefile( '.*' )}.db" | |
end | |
if OPTS.has_key? :schema then | |
schema_file = OPTS[:schema] | |
else | |
schema_file = nil | |
end | |
create_table_statement = generate_create_table_query( input_file ) | |
include SQLite3 | |
db_context = Database.new( output_file ) | |
# | |
# TODO: | |
# 1. create_table_statement を execute してテーブルを作成する。 | |
# 2. 生成したテーブルに残りの行を挿入するために insert クエリを生成するメソッドを書く。 | |
# 3. (2) を使って挿入する。 | |
# 4. 少なくとも 2 回 tsv ファイルを読み込むことになるので、1 回だけ読み込むようにする。 | |
# | |
db_context.close | |
rescue => e | |
$stderr.puts "#{$0}: #{e}" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment