sqoop 导入mysql blob字段,Sqoop导入的数据格式问题
Sqoop簡(jiǎn)單介紹
Sqoop是用來(lái)在Hadoop平臺(tái)和其他結(jié)構(gòu)性存儲(chǔ)(比如關(guān)系型數(shù)據(jù)庫(kù))之間解決大量數(shù)據(jù)傳輸問(wèn)題的工具。也就是說(shuō)可以從Oracle,MySQL,PostgreSQL等數(shù)據(jù)庫(kù)中將數(shù)據(jù)傳輸?shù)紿DFS,Hive,HBase上,反之也可以。
簡(jiǎn)單說(shuō)一下Sqoop的原理。它實(shí)際上就是將導(dǎo)入導(dǎo)出這個(gè)工作通過(guò)指令翻譯成一個(gè)java文件,然后通過(guò)MapReduce來(lái)執(zhí)行格式的轉(zhuǎn)換和傳輸工作。
具體怎么配置,怎么使用,官方文檔在這里 ——Sqoop User Guide 。
官方文檔寫(xiě)得很全,其他博客其實(shí)沒(méi)有官方文檔寫(xiě)的清楚。
問(wèn)題描述
我寫(xiě)了個(gè)接口能夠根據(jù)用戶輸入的數(shù)據(jù)庫(kù)類(lèi)型,表名,數(shù)據(jù)庫(kù)名,就可以自動(dòng)生成對(duì)應(yīng)的Sqoop腳本,用戶自己就不用額外寫(xiě)一份可能還會(huì)出錯(cuò)的腳本,能直接用Sqoop將數(shù)據(jù)庫(kù)中的數(shù)據(jù)抽取到Hive上。
以O(shè)racle作為例子,Oracle中的數(shù)據(jù)抽出來(lái)轉(zhuǎn)換為Java是由對(duì)應(yīng)的映射關(guān)系的。問(wèn)題就在于有些數(shù)據(jù)類(lèi)型格式在Java中沒(méi)有找到對(duì)應(yīng)的映射關(guān)系,導(dǎo)致Sqoop導(dǎo)入失敗。比如Oracle中的Bit,Blob,Clob,LongText字段。因此在執(zhí)行腳本的時(shí)候會(huì)出現(xiàn)導(dǎo)入失敗的問(wèn)題。
后來(lái)通過(guò)閱讀官方文檔后得知,Sqoop在遇到這些特殊字段類(lèi)型時(shí),是可以強(qiáng)制轉(zhuǎn)換的,具體看 SqoopUserGuide - controlling type mapping 。
--map-column-java 重寫(xiě)SQL到Java類(lèi)型的映射
--map-column-hive 重寫(xiě)Hive到Java類(lèi)型的映射
舉個(gè)例子,比如說(shuō)SQL中的原先字段id強(qiáng)制轉(zhuǎn)為String類(lèi)型,字段value強(qiáng)制轉(zhuǎn)為Integer類(lèi)型(不管他們?cè)臼鞘裁?,那么:
$ sqoop import ... --map-column-java id=String,value=Integer
這樣就可以解決Sqoop在導(dǎo)入導(dǎo)出數(shù)據(jù)的時(shí)候格式錯(cuò)誤的問(wèn)題。
具體SQL類(lèi)型中哪些格式對(duì)應(yīng)著HIVE中的哪些格式,看這個(gè)鏈接: sqoop導(dǎo)數(shù)類(lèi)型不支持解決辦法:Hive does not support the SQL type for column 。參考這個(gè)鏈接,接下來(lái)做一個(gè)關(guān)系型數(shù)據(jù)庫(kù)數(shù)據(jù)類(lèi)型映射Java的對(duì)應(yīng)類(lèi)型的歸納。
對(duì)應(yīng)數(shù)據(jù)類(lèi)型
以O(shè)racle數(shù)據(jù)庫(kù)為例,它可以映射到j(luò)ava的數(shù)據(jù)類(lèi)型:
public String toJavaType(int sqlType) {
// Mappings taken from:
// http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/mapping.html
if (sqlType == Types.INTEGER) {
return "Integer";
} else if (sqlType == Types.VARCHAR) {
return "String";
} else if (sqlType == Types.CHAR) {
return "String";
} else if (sqlType == Types.LONGVARCHAR) {
return "String";
} else if (sqlType == Types.NVARCHAR) {
return "String";
} else if (sqlType == Types.NCHAR) {
return "String";
} else if (sqlType == Types.LONGNVARCHAR) {
return "String";
} else if (sqlType == Types.NUMERIC) {
return "java.math.BigDecimal";
} else if (sqlType == Types.DECIMAL) {
return "java.math.BigDecimal";
} else if (sqlType == Types.BIT) {
return "Boolean";
} else if (sqlType == Types.BOOLEAN) {
return "Boolean";
} else if (sqlType == Types.TINYINT) {
return "Integer";
} else if (sqlType == Types.SMALLINT) {
return "Integer";
} else if (sqlType == Types.BIGINT) {
return "Long";
} else if (sqlType == Types.REAL) {
return "Float";
} else if (sqlType == Types.FLOAT) {
return "Double";
} else if (sqlType == Types.DOUBLE) {
return "Double";
} else if (sqlType == Types.DATE) {
return "java.sql.Date";
} else if (sqlType == Types.TIME) {
return "java.sql.Time";
} else if (sqlType == Types.TIMESTAMP) {
return "java.sql.Timestamp";
} else if (sqlType == Types.BINARY
|| sqlType == Types.VARBINARY) {
return BytesWritable.class.getName();
} else if (sqlType == Types.CLOB) {
return ClobRef.class.getName();
} else if (sqlType == Types.BLOB
|| sqlType == Types.LONGVARBINARY) {
return BlobRef.class.getName();
} else {
// TODO(aaron): Support DISTINCT, ARRAY, STRUCT, REF, JAVA_OBJECT.
// Return null indicating database-specific manager should return a
// java data type if it can find one for any nonstandard type.
return null;
}
建表時(shí),Oracle映射到Hive的數(shù)據(jù)類(lèi)型(查看org.apache.sqoop.hive.HiveTypes)
public static String toHiveType(int sqlType) {
switch (sqlType) {
case Types.INTEGER:
case Types.SMALLINT:
return "INT";
case Types.VARCHAR:
case Types.CHAR:
case Types.LONGVARCHAR:
case Types.NVARCHAR:
case Types.NCHAR:
case Types.LONGNVARCHAR:
case Types.DATE:
case Types.TIME:
case Types.TIMESTAMP:
case Types.CLOB:
return "STRING";
case Types.NUMERIC:
case Types.DECIMAL:
case Types.FLOAT:
case Types.DOUBLE:
case Types.REAL:
return "DOUBLE";
case Types.BIT:
case Types.BOOLEAN:
return "BOOLEAN";
case Types.TINYINT:
return "TINYINT";
case Types.BIGINT:
return "BIGINT";
default:
// TODO(aaron): Support BINARY, VARBINARY, LONGVARBINARY, DISTINCT,
// BLOB, ARRAY, STRUCT, REF, JAVA_OBJECT.
return null;
}
}
特殊的字段類(lèi)型
通過(guò)使用強(qiáng)制轉(zhuǎn)換的方式來(lái)導(dǎo)入。
Oracle中的Blob,LongBlob導(dǎo)入到Hive中對(duì)應(yīng)是String。要在腳本中添加如下配置,在映射成java的時(shí)候映射為String,Hive中也要映射為String:
$ sqoop import ... --map-column-java [字段名]=String \
--map-column-hive [字段名]=String
Oracle的Bit字段則映射為String。若是按照常規(guī)映射,則會(huì)映射成boolean的true或者false。而原先在數(shù)據(jù)庫(kù)中展示的則是0和1。添加以下配置:
$ sqoop import ... --map-column-java [字段名]=String
** 憑之前做項(xiàng)目印象打的,如果有錯(cuò)誤請(qǐng)指正。
總結(jié)
以上是生活随笔為你收集整理的sqoop 导入mysql blob字段,Sqoop导入的数据格式问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: php写文件 效率,php中读写文件与读
- 下一篇: linux cmake编译源码,linu