Apache Sqoopにハマる

本格的に使ってみると,色々とハマりました.
CDH4 + Apache Sqoop - なぜか数学者にはワイン好きが多い


MySQLからimportしてHiveに入れてからMicrosoft SQL Serverにexportするとエラーになるパターン

* 不適切な構文があります

$ sqoop export --connect 'jdbc:sqlserver://server:1234;database=DATA' --username 'hoge_admin' --password 'hoge_pass'  --table DB_DATA --export-dir /user/hive/warehouse/game_log  --input-fields-terminated-by '\001' --optionally-enclosed-by "\'" -m 1

(snip)

Caused by: java.io.IOException: java.sql.BatchUpdateException: '3' 付近に不適切な構文があります。

(snip)

「3」ってなんや!と思ってデータノードのログ(logs/userlog/****/syslog)を調べると,

2013-11-06 10:58:46,631 INFO [main] org.apache.sqoop.mapreduce.sqlserver.SqlServerExportBatchOutputFormat: Using query INSERT INTO [DB_DATA] (game_type, 3d_graphics) VALUES (?, ?)
2013-11-06 10:58:47,017 ERROR [Thread-8] org.apache.sqoop.mapreduce.AsyncSqlOutputFormat: Got exception in update thread: java.sql.BatchUpdateException: '3' 付近に不適切な構文があります。

こんなストアドプロシジャの痕跡が.
データ中の3じゃなくて,テーブルの中のに,3で始まるカラム名がありました.Sqoopは[3d_graphics]などとやってくれなくてエラーになるので,SQL Serverの中の数字で始まるカラム名を変更することにしました.

* can not be represented as java.sql.Timestamp

Caused by: java.sql.SQLException: Value '
0000000-00-00 00:00:000000-00-00 00:00:000000' can not be represented as java.sql.Timestamp

この2行の他にも怪しいエラーログが出ているのでどれが原因か迷いますが,timestampの値が不正なせい.

コネクトストリングを,これから

jdbc:sqlserver://server:1234;database=DATA

こう変更することで解決.

jdbc:sqlserver://server:1234;database=DATA?zeroDateTimeBehavior=convertToNull

* NumberFormatException

Caused by: java.lang.NumberFormatException: For input string: "true"
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
mysql -h mysqlserver -u mysql_admin --password=mysql_pass -e 'describe game_db' members
+----------------------+-------------+------+-----+---------+-------+
| Field                | Type        | Null | Key | Default | Extra |
+----------------------+-------------+------+-----+---------+-------+
| name                 | varchar(45) | NO   |     | NULL    |       |
| is_valid             | tinyint(1)  | NO   |     | 1       |       |
+----------------------+-------------+------+-----+---------+-------+

hive -e 'describe members'
name     string
is_valid        boolean

tinyint(1)がbooleanに変換されてしまっているのが原因.
コネクトストリングを,これから

jdbc:sqlserver://server:1234;database=DATA

こう変更することで解決.

jdbc:sqlserver://server:1234;database=DATA?tinyInt1isBit=false

実際には,コネクトストリングは統一してこうしちゃいました.

jdbc:sqlserver://server:1234;database=DATA?zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false