今日もプログラミング

IT技術とかプログラミングのこととか特にJavaを中心に書いていきます

embulk-output-jdbcの型についてまとめた

embulk-output-jdbcではいろいろな型が出てくる。

ややこしいので、現在の実装に基づいてまとめてみた。

 

embulk-output-jdbcに出てくる型の種類

  • 入力の型
  • column_optionsのvalue_type
  • column_optionsのtype
  • 出力先テーブルの列の型

 

入力の型

embulk内部の型であり、boolean/long/double/string/timestampのいずれかである。timestampにはフォーマット指定もあり、日付のみや時刻のみといいう指定もできる。

入力の型は、例えばCSV入力の場合はymlファイルで定義する。

embulk-input-jdbcを使う場合は入力元テーブルの列の型により自動的に決まる。

テーブルの列の型(java.sql.Types)入力の型
BOOLEAN
BIT
boolean
TINYINT
SMALLINT
INT
BIGINT
long
DOUBLE
FLOAT
REAL
NUMERIC
DECIMAL
double
CHAR
VARCHAR
LONGVARCHAR
CLOB
NCHAR
NVARCHAR
LONGNVARCHAR
string
DATE timestamp (%Y-%m-%d)
TIME timestamp (%H:%M:%S)
TIMESTAMP timestamp (%Y-%m-%d %H:%M:%S)

 

column_optionsのtype

必要に応じてymlファイルで定義する。

embulk-output-jdbcにより出力先のテーブルが生成される際の列の型を表す。

未指定の場合は、入力の型により自動的に決まる。

入力型テーブルの列の型
boolean BOOLEAN
long BIGINT
double DOUBLE PRECISION
string CLOB
timestamp TIMESTAMP

 

column_optionsのvalue_type

必要に応じてymlファイルで定義する。

DBに出力する際の型を表す。

基本的には、java.sql.PreparedStatementのsetXXXメソッドに対応する。

value_type動作
boolean setBoolean
byte setByte
short setShort
int setInt
long setLong
float setFloat
double setDouble
decimal setBigDecimal
string setString
nstring setNString
date setObject(java.sql.Date)
time setObject(java.sql.Time)
timestamp setObject(java.sql.Timestamp)
null setNull
pass 入力型による
入力型動作
boolean setBoolean
long setLong
double setDouble
string setString
timestamp setObject(java.sql.Timestamp)
coalesce 未設定の場合と同じ

 

未指定の場合は、出力先DBの型に応じて自動的に決まる。

テーブルの列の型(java.sql.Types)動作
BOOLEAN
BIT
setBoolean
TINYINT setByte
SMALLINT setShort
INTEGER setInt
BIGINT setLong
FLOAT
DOUBLE
setDouble
REAL setFloat
NUMERIC
DECIMAL
setBigDecimal
CHAR
VARCHAR
LONGVARCHAR
CLOB
setString
NCHAR
NVARCHAR
LONGNVARCHAR
setNString
DATE setObject(java.sql.Date)
TIME setObject(java.sql.Time)
TIMESTAMP setObject(java.sql.Timestamp)

 

例えば、CSVファイルを入力してDBに出力するとき、入力の型がlong、column_optionsのvalue_typeがdouble、テーブルの列の型がDECIMALであれば、以下のように変換されることになる。

  文字列(CSVファイル)
    ↓ CSVパーサ
  long値 (入力の型)
    ↓ embulk-output-jdbcのColumnSetter
  double値 (column_optionsのvalue_type)
    ↓ DB側
  DECIMAL値

 

結局どう設定すればよいのか?

基本的には、なるべく余計な変換はしたくない。

エラーが起きたり、情報が落ちたり、パフォーマンスが劣化したりする恐れがあるからである。

例えばテキストファイルを入力してDBに出力する場合は、以下の2パターンがありそうだ。

  • 入力の型をDB側の型に合わせる
  • 入力の型をstringにしてそのままDBに出力する(column_optionsのvalue_typeをpassに)

前者の方がきれいだが、パフォーマンスは後者の方が速いかも。

桁数の大きい数値型(DECIMAL(18,3)とか)では、後者にする必要がある。

Embulk内部の数値型はlongとdoubleだが、これらに変換すると誤差が出てしまうからだ。

なお、DBMSJDBCドライバによっては変なjava.sql.Typesの値を返す場合があるので、このような場合もcolumn_optionsのvalue_typeを設定する必要がある。

 

Embulk 0.6.8
embulk-output-jdbc 0.3.0
embulk-input-jdbc 0.4.0