使用带有--as-avrodatafile选项的Sqoop时出现日期字段

时间:2014-08-26 19:58:54

标签: sqoop sqoop2

以下是我的问题的要点。

ENV: Hadoop 2(CDH5.1) 数据库:oracle 11g

方案: 我将事实和维度表从数据库平滑到hdfs。最初,我遇到了处理空值的挑战(使用--null-string和--non-null-string处理),根据建议将其设置为\ N.当构建的hive表甚至包含日期和数字的字符串字段时,一切都很好。

到目前为止的解决方案 根据建议,我转向使用Avro格式导入。我已经在avro数据上构建了hive表,并且我能够查询表。现在我需要创建Hive连接并将所有字段转换为所需类型,例如日期为date / timestamps,数字为int / bigint等。在sqooping之后,创建的avro模式已将所有日期字段转换为long和hive表显示那些列的bigint。

我对sqoop如何处理空值以及如何在hive / hdfs MR等中处理它们感到困惑。

你能否建议任何可以利用的做法?

由于 卡塔斯

3 个答案:

答案 0 :(得分:2)

这也是我的问题。当我从镶木地板表格中压缩架构时...因为Parquet将时间戳存储为bigint。所以我猜基础问题是没有单独数据类型来存储时间戳的镶木地板。不要经常使用AVRO,但我认为AVRO也是如此。因此,如果您从Oracle日期/时间戳sqoop到一组镶木地板/ avro文件,那么存储类型(bigint)就是它的存储方式,而不是你想要的方式(时间戳/日期)。

从UNIX纪元时间(1970年1月1日)起,该时间存储为毫秒的数量。 Hive / Spark / Impala函数 from_unixtime ()需要,因此解决方法是将这些ms值转换为s分辨率:

SELECT .. 
, from_unixtime(cast(bigint_column/1000 as bigint))

所以你会看到如下的时间戳:

 1999-04-14 06:00:00 
 1999-04-15 06:00:00

注意6小时轮班。在我的情况下,原始Oracle的数据类型是DATE,没有任何时间部分(00:00:00),但由于我的时区(MST),我的时间被移动了06小时。所以要获得确切的日期:

SELECT .. 
, from_unixtime(cast(bigint_column/1000 - 6*3600 as bigint))

导致:

 1999-04-14 00:00:00 
 1999-04-15 00:00:00

PS。 “实木复合地板的数据类型注意事项” http://www.cloudera.com/documentation/archive/impala/2-x/2-1-x/topics/impala_parquet.html#parquet_data_types_unique_1

INT96 - > TIMESTAMP

答案 1 :(得分:1)

谢谢Gergely。我们为克服这个问题而采用的方法是,当sqooped到hdfs时,sqoop将日期字段导入为字符串类型。这是使用

实现的

sqoop --option-file $ OPTION_FILE_NAME \ --table $ TABLE_NAME \ --map-column-java DAY_END_DTE = String \ --target-dir $ TARGET_DIR \ --as-avrodatafile

这会导致时间戳信息被平滑为字符串' yyyy-mm-dd hh:mm:ss.f'可以转换为日期字段的格式。

答案 2 :(得分:0)

这不是解决方案, 这是一种解决方法

您可以使用以下命令将导入的数据转换为时间戳:

从imported_table中选择强制转换(long_column作为TIMESTAMP);

BR, 盖尔盖伊