Sqoop导入的数据格式问题

2019-03-28  本文已影响0人  _赵开心_

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 <mapping> 重写SQL到Java类型的映射
--map-column-hive <mapping> 重写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的对应类型的归纳。

对应数据类型

  1. 以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;  
  }  
  1. 建表时,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;  
     }  
 }  
  1. 特殊的字段类型
    通过使用强制转换的方式来导入。
$ sqoop import ... --map-column-java <mapping> [字段名]=String \
 --map-column-hive <mapping> [字段名]=String
$ sqoop import ... --map-column-java <mapping> [字段名]=String




** 凭之前做项目印象打的,如果有错误请指正。

上一篇 下一篇

猜你喜欢

热点阅读