在Athena上转换为带时区的时间戳失败

时间:2018-06-13 08:52:45

标签: sql date hive amazon-athena timestamp-with-timezone

我试图创建以下视图:

// Filter input fields object
var filterData = {
  "title" : "Things You dont know",
  "author": "Rohit Jindal",
  "year": 1953
};

// Data object
var items = [
 {
   "id":"1",
   "author": "Chinua Achebe",
   "country": "Nigeria",
   "imageLink": "images/things-fall-apart.jpg",
   "language": "English",
   "link": "https://en.wikipedia.org/wiki/Things_Fall_Apart\n",
   "pages": 209,
   "title": "Things Fall Apart",
   "year": 1958
 },{
   "id":"2",
   "author": "Rohit Jindal",
   "country": "Nigeria",
   "imageLink": "images/things-fall-apart.jpg",
   "language": "English",
   "link": "https://en.wikipedia.org/wiki/Things_Fall_Apart\n",
   "pages": 209,
   "title": "Things You dont know",
   "year": 1953
 },{
   "id":"3",
   "author": "Author Name",
   "country": "Nigeria",
   "imageLink": "images/things-fall-apart.jpg",
   "language": "English",
   "link": "https://en.wikipedia.org/wiki/Things_Fall_Apart\n",
   "pages": 209,
   "title": "Welcome to JavaScript",
   "year": 1947
 }
];

// Logic to check for all the three filters data and give the output
var filteredItems = items.filter(obj => {
   if ((obj.title.toLowerCase().indexOf(filterData.title.toLowerCase()) > -1) &&
       (obj.author.toLowerCase().indexOf(filterData.author.toLowerCase()) > -1) &&
       (obj.year == filterData.year)) {
       return obj;
     }
});

console.log(filteredItems);

它给了我以下错误:

  

您的查询有以下错误:   不支持的Hive类型:带时区的时间戳

然而,当我在它上面运行查询时,它运行正常,而From_iso8601_timestamp被称为here作为有效的日期函数。

谁能告诉我我做错了什么?

3 个答案:

答案 0 :(得分:7)

不幸的是,雅典娜不完全支持Presto的所有功能,从技术上讲,它比Presto落后几个版本。有一些尝试使Athena与AWS Glue Metastore紧密集成,而AWS Glue Metastore基于Hive的metastore有一些不一致之处。我希望Spark,Hive,Glue,Athena,Presto等人可以与同一个metastore一起使用,这样可以使生活更轻松,但是回到您的问题:

document about an older teradata fork of Presto提到了presto中时间戳的一些问题:

  

Presto声明带/不带时区的时间戳的方法不是   sql标准。在Presto中,二者都使用单词TIMESTAMP声明,   例如TIMESTAMP'2003-12-10 10:32:02.1212'或TIMESTAMP'2003-12-10   10:32:02.1212 UTC'。确定时间戳记是否带有   时区,具体取决于您是否在时区末包含时区   时间戳记。在其他系统中,时间戳被明确声明为   带有时区的时间戳或没有时区的时间戳

您已链接以显示该函数返回该不受支持的类型timestamp with timezone的值的presto文档,因此您需要将其强制转换为其他受支持的类型。 Athena允许函数并强制转换为当时不支持的数据类型是非常不愉快的。

您需要做的是在该函数调用周围使用CAST()函数,这会将类型从timestamp with time zone更改为timestamp

不幸的是,您可能无法将字符串直接转换为时间戳,尽管这取决于字符串的格式。您也不能使用在字符串之前写timestamp的强制转换样式,例如由于以下原因我无法做timestamp '2018-01-01 15:00:00'

from_iso1601_timestamp()函数返回的类型

SELECT typeof("real_date") AS real_date_type
FROM
(
SELECT From_iso8601_timestamp('2018-01-01T15:00:00Z') as "real_date"
)
  

带有时区的时间戳

这不起作用

SELECT typeof("real_date") AS real_date_type
FROM
(
SELECT CAST('2018-01-01T15:00:00Z' AS timestamp) as "real_date"
)
  

SQL错误[FAILED]:INVALID_CAST_ARGUMENT:无法将值强制转换为   时间戳

这种类型的转换也会返回带有时区的时间戳:(

请注意,此方法的SELECT部分​​有效,并且说它是timestamp,但是根据上述Teradata页面上的信息,这样做实际上是timestamp with timezone的别名,并且你会得到一个错误

CREATE OR replace VIEW test 
AS 
SELECT typeof( "real_date" ) AS real_date_type
FROM
(
SELECT  timestamp '2018-01-01 15:00:00' as "real_date"
)
  

SQL错误[FAILED]:无法初始化类   com.facebook.presto.util.DateTimeZoneIndex

这行得通

CREATE OR REPLACE VIEW test
AS
SELECT typeof("real_date") AS real_date_type
FROM
(
SELECT CAST(From_iso8601_timestamp('2018-01-01T15:00:00Z') AS timestamp) as "real_date"
)

答案 1 :(得分:0)

对我最近正在研究的东西进行类似的研究。 AWS支持为我提供了达沃斯解决方案,但最终并没有解决我的问题。最终对我起作用的解决方案是:

create or replace view db_name.vw_name AS
select
    from_unixtime(cast(to_unixtime(current_timestamp) AS bigint)) as field_name
from db_name.tbl_name

这会将current_timestamp的输出timestamp with time zone转换为timestamp

如果要验证字段的数据类型,可以使用:

select typeof(field_name) from db_name.vw_name

希望有帮助!

答案 2 :(得分:0)

您可以在Athena over Timestamp数据类型(dt)中使用以下语法:

SELECT id,dt,dt AT TIME ZONE 'America/New_York' as dateTimeNY FROM Table