hive external table on avro timestamp 字段返回一样长

hive external table on avro timestamp field returning as long

我有具有单列时间戳列的 avro 数据,现在我正在尝试在 avro 文件之上创建外部配置单元 table。只要数据保存在 avro 中,我希望 avro 符合逻辑当我查询配置单元 table 时,输入处理转换回时间戳的类型。但这并没有发生在它简单地返回 long 值时。我怎样才能让它按预期工作?

PS :我正在使用 spark 2.3 和数据块 com.databrospark-avro_2.11

    <dependency>
        <groupId>com.databricks</groupId>
        <artifactId>spark-avro_2.11</artifactId>
        <version>4.0.0</version>
    </dependency>

STEP1 : 将时间戳值存储到 avro

val startTs=java.sql.Timestamp.valueOf("2020-05-11 14:17:57.188")
val df=Seq(startTs).toDF
df.write.avro("/test")
val avroDf=spark.read.avro("/test")
avroDf.show(false)

+-------------+
|value        |
+-------------+
|1589221077188|
+-------------+


AVSC file  generated using avro-tools from the avro data files 
test.avsc 
{
  "type" : "record",
  "name" : "topLevelRecord",
  "fields" : [ {
    "name" : "value",
    "type" :  "long", "logicalType": "timestamp-millis" 
  } ]
}

hdfs dfs -copyFromLocal -f test.avsc /tmp/test.avsc

第 2 步:在 AVRO 数据上创建外部 HIVE TABLE

DROP TABLE IF EXISTS test_a;

CREATE EXTERNAL TABLE  test_a 
STORED AS AVRO
LOCATION '/tenants/gwm/idr/tmp/test'
TBLPROPERTIES ('avro.schema.url'='/tmp/test.avsc');

msck repair table test_a;
select * from  test_a;

+----------------+--+
|  test_a.value  |
+----------------+--+
| 1589221077188  |
+----------------+--+

我试图获取时间戳值而不是这个长值。

来自 Avro 规范:

timestamp-millis 逻辑类型注释 Avro long,其中 long 存储从 unix 纪元开始的毫秒数,1970 年 1 月 1 日 00:00:00.000 UTC。

也许这个link可以帮到你

Creating a Proper avro schema for timestamp record

另一种方法是从 hive 查询 long 值或将时间戳存储为 Spark 应用程序中的字符串值:

SELECT CONCAT(FROM_UNIXTIME(CAST(SUBSTR(CAST(1589221077188 AS STRING),1,10) AS BIGINT)),'.', SUBSTR(CAST(1589221077188 AS STRING),11,13)) AS timestamp; 

SELECT CONCAT(FROM_UNIXTIME(CAST(SUBSTR(CAST(time AS STRING),1,10) AS BIGINT)),'.', SUBSTR(CAST(time AS STRING),11,13)) AS timestamp; 
"2020-05-11 14:17:57.188"

希望对您有所帮助。