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?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?tinyInt1isBit=false
実際には,コネクトストリングは統一してこうしちゃいました.
jdbc:sqlserver://server:1234;database=DATA?zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false