sqoop 导入mysql blob字段,Sqoop导入的数据格式问题
Sqoop簡單介紹
Sqoop是用來在Hadoop平臺和其他結構性存儲(比如關系型數據庫)之間解決大量數據傳輸問題的工具。也就是說可以從Oracle,MySQL,PostgreSQL等數據庫中將數據傳輸到HDFS,Hive,HBase上,反之也可以。
簡單說一下Sqoop的原理。它實際上就是將導入導出這個工作通過指令翻譯成一個java文件,然后通過MapReduce來執行格式的轉換和傳輸工作。
具體怎么配置,怎么使用,官方文檔在這里 ——Sqoop User Guide 。
官方文檔寫得很全,其他博客其實沒有官方文檔寫的清楚。
問題描述
我寫了個接口能夠根據用戶輸入的數據庫類型,表名,數據庫名,就可以自動生成對應的Sqoop腳本,用戶自己就不用額外寫一份可能還會出錯的腳本,能直接用Sqoop將數據庫中的數據抽取到Hive上。
以Oracle作為例子,Oracle中的數據抽出來轉換為Java是由對應的映射關系的。問題就在于有些數據類型格式在Java中沒有找到對應的映射關系,導致Sqoop導入失敗。比如Oracle中的Bit,Blob,Clob,LongText字段。因此在執行腳本的時候會出現導入失敗的問題。
后來通過閱讀官方文檔后得知,Sqoop在遇到這些特殊字段類型時,是可以強制轉換的,具體看 SqoopUserGuide - controlling type mapping 。
--map-column-java 重寫SQL到Java類型的映射
--map-column-hive 重寫Hive到Java類型的映射
舉個例子,比如說SQL中的原先字段id強制轉為String類型,字段value強制轉為Integer類型(不管他們原本是什么),那么:
$ sqoop import ... --map-column-java id=String,value=Integer
這樣就可以解決Sqoop在導入導出數據的時候格式錯誤的問題。
具體SQL類型中哪些格式對應著HIVE中的哪些格式,看這個鏈接: sqoop導數類型不支持解決辦法:Hive does not support the SQL type for column 。參考這個鏈接,接下來做一個關系型數據庫數據類型映射Java的對應類型的歸納。
對應數據類型
以Oracle數據庫為例,它可以映射到java的數據類型:
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;
}
建表時,Oracle映射到Hive的數據類型(查看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;
}
}
特殊的字段類型
通過使用強制轉換的方式來導入。
Oracle中的Blob,LongBlob導入到Hive中對應是String。要在腳本中添加如下配置,在映射成java的時候映射為String,Hive中也要映射為String:
$ sqoop import ... --map-column-java [字段名]=String \
--map-column-hive [字段名]=String
Oracle的Bit字段則映射為String。若是按照常規映射,則會映射成boolean的true或者false。而原先在數據庫中展示的則是0和1。添加以下配置:
$ sqoop import ... --map-column-java [字段名]=String
** 憑之前做項目印象打的,如果有錯誤請指正。
總結
以上是生活随笔為你收集整理的sqoop 导入mysql blob字段,Sqoop导入的数据格式问题的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: php写文件 效率,php中读写文件与读
- 下一篇: php生成首页 教程,简单静态页生成 过
