avro timestamp字段上的hive外部表返回long

ngynwnxp  于 2021-06-24  发布在  Hive
关注(0)|答案(1)|浏览(540)

我有一个avro数据,它有一个单独的列timestamp列,现在我正在尝试在avro文件上创建外部配置单元表。数据在avro中保存的时间很长,我希望avro逻辑类型在我查询配置单元表时处理回timestamp的转换。但这并不是简单地将多头价值收回。我怎样才能让它按预期工作?
ps:我正在使用spark 2.3和databricks com.databrospark-avroèu 2.11

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

步骤1:将时间戳值存储到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数据上创建外部配置单元表

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  |
+----------------+--+

我试图得到timestamp值,而不是这个长值。

vx6bjr1n

vx6bjr1n1#

根据avro规范:
timestamp millis逻辑类型注解avro long,其中long存储unix epoch(1970年1月1日00:00:00.000 utc)的毫秒数。
也许这个链接可以帮你
为时间戳记录创建适当的avro模式
另一种方法是从配置单元中查询长值,或者从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"

我希望这有帮助。

相关问题