今日もプログラミング

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

embulk-input-jdbc 0.5.0では型を指定できるようになった

以前embulk-input-jdbcをOracleで試したときは、いろいろと問題があった。

  • 整数なのに小数点以下が出力される
  • 大きな数値が指数表記で出力される
  • DATE型なのに時分秒が出力される
  • TIMESTAMPの秒未満が出力されない

しかし、embulk-input-jdbc 0.5.0 (および embulk-input-oracle 0.5.0)では、これらが全て解決できた!

 

テーブルの準備

この前と同じく、テーブルを準備する。

CREATE TABLE INPUT_TEST (
    ID     NUMBER(8,0),
    NUM    NUMBER(12,2),
    STR    CHAR(8),
    VARSTR VARCHAR2(8),
    DT     DATE,
    TIME0  TIMESTAMP(0),
    TIME6  TIMESTAMP,
    TIME9  TIMESTAMP(9),
    PRIMARY KEY(ID)
);

 

データの準備

これもこの前と同じく、CSVファイルを準備する。

1,,,,,,,
2,123.4,chr1,varchr1,2015-04-24,2015-04-24 01:02:03,2015-04-24 01:02:03.12345,2015-04-24 01:02:03.12345678
3,1234567890.12,chr12345,varchr12,2015-12-31,2015-12-31 23:59:59,2015-12-31 23:59:59.123456,2015-12-31 23:59:59.123456789

 

で、embulk-output-oracleで流し込む。

in:
  type: file
  path_prefix: 'data/output-oracle.csv'
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    header_line: false
    columns:
    - {name: ID, type: long}
    - {name: NUM, type: string}
    - {name: STR, type: string}
    - {name: VARSTR, type: string}
    - {name: DT, type: timestamp, format: '%Y-%m-%d'}
    - {name: TIME0, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: TIME6, type: timestamp, format: '%Y-%m-%d %H:%M:%S.%N'}
    - {name: TIME9, type: string}
out:
    type: oracle
    host: localhost
    database: TESTDB
    user: TEST_USER
    password: test_pw
    table: INPUT_TEST
    mode: insert_direct
    insert_method: normal
    driver_path: 'driver/ojdbc7.jar'
    column_options:
      TIME9: {value_type: pass}

こんなymlファイルを用意して、

embulk run output-oracle.yml

を実行すればOK。

以前は「mode: insert」だったが、「mode: insert_direct」に変わっている。

また、Embulkのtimestamp型を使うとマイクロ秒未満が切り捨てられてしまうため、TIME9列はstringのまま挿入するようにしている。

 

embulk-input-oracleCSVを出力する

embulk-input-jdbc 0.5.0から、各列の型を明示的に指定できるようになった。

これを利用すれば、各列の値を正確に出力することができる。

ymlファイルはこんな感じ。

in:
  type: jdbc
  driver_path: driver/ojdbc7.jar
  host: localhost
  database: TESTDB
  user: TEST_USER
  password: test_pw
  table: INPUT_TEST
  select: "*"
  column_options:
    ID: {type: long}
    NUM: {type: string}
    DT: {type: timestamp, timestamp_format: '%Y-%m-%d'}
    TIME6: {type: timestamp, timestamp_format: '%Y-%m-%d %H:%M:%S.%6N'}
    TIME9: {type: timestamp, timestamp_format: '%Y-%m-%d %H:%M:%S.%9N'}

out:
  type: file
  path_prefix: input-oracle
  file_ext: .csv
  formatter:
    type: csv

 

ID列はデフォルトだとdoubleになり、小数点以下が出力されてしまうので、明示的にlongを指定している。

NUM列もデフォルトだとdoubleで、大きな数が指数表記になってしまうので、stringを指定している。

DT列、TIME6列、TIME9列は、明示的にフォーマットを指定している。

 

embulk run input-oracle.yml

を実行すると…、

ID,NUM,STR,VARSTR,DT,TIME0,TIME6,TIME9
1,,,,,,,
2,123.4,chr1    ,varchr1,2015-04-24,2015-04-24 01:02:03,2015-04-24 01:02:03.123450,2015-04-23 16:02:03.123456780
3,1234567890.12,chr12345,varchr12,2015-12-31,2015-12-31 23:59:59,2015-12-31 23:59:59.123456,2015-12-31 14:59:59.123456789

正しいCSVが出力された!

 

CHARの後ろのスペースとか、TIMESTAMPの秒未満の後ろの0とかは元のCSVと違うが、問題無いでしょう。

 

embulk 0.6.12
embulk-output-oracle 0.4.0
embulk-input-oracle 0.5.0
Oracle 12c