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 | 入力型による
|
||||||||||||
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だが、これらに変換すると誤差が出てしまうからだ。
なお、DBMSやJDBCドライバによっては変なjava.sql.Typesの値を返す場合があるので、このような場合もcolumn_optionsのvalue_typeを設定する必要がある。
Embulk | 0.6.8 |
embulk-output-jdbc | 0.3.0 |
embulk-input-jdbc | 0.4.0 |