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 |