2

以下是我的问题的要点。

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

场景:我正在将数据库中的事实和维度表放入 hdfs 中。最初,我在处理根据建议设置为 \N 的空值(使用 --null-string 和 --non-null-string 处理)时遇到了挑战。当构建的 hive 表包含日期和数字的字符串字段时,一切都很好。

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

我对 sqoop 如何处理 null 以及如何在 hive/hdfs MR 等中处理这些感到困惑。

您能否提出任何可以利用的已采用实践?

谢谢文卡特什

4

3 回答 3

3

这对我来说也是个问题。当我从镶木地板表中导入模式时......因为 Parquet 将时间戳存储为 bigint。所以我想根本问题是没有单独的数据类型来存储时间戳的镶木地板。不要经常使用 AVRO,但我认为 AVRO 也是如此。因此,如果您从 Oracle 日期/时间戳记入一组 parquet/avro 文件,那么存储类型 (bigint) 就是它的存储方式,而不是您希望如何访问它的方式(时间戳/日期)。

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

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

所以你会看到像这样的时间戳:

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

注意 6 小时轮班。在我的情况下,原始 O​​racle 的数据类型是没有任何时间部分 (00:00:00) 的 DATE,但由于我的时区 (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

附言。“Parquet 表的数据类型注意事项” http://www.cloudera.com/documentation/archive/impala/2-x/2-1-x/topics/impala_parquet.html#parquet_data_types_unique_1

INT96 -> 时间戳

于 2016-02-23T22:54:54.760 回答
1

谢谢格格利。我们为解决这个问题而采取的方法是在将 sqoop 导入 hdfs 时将日期字段作为字符串类型导入。这是使用实现的

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' 格式的字符串被 sqooped,可以转换为日期字段。

于 2014-10-07T03:55:22.380 回答
0

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

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

从imported_table中选择cast(long_column as TIMESTAMP);

BR,格格利

于 2014-09-29T09:52:54.263 回答