簡體   English   中英

在 Athena 上轉換為帶時區的時間戳失敗

[英]converting to timestamp with time zone failed on Athena

我正在嘗試創建以下視圖:

CREATE OR REPLACE VIEW view_events AS 
(
   SELECT
     "rank"() OVER (PARTITION BY "tb1"."innerid" ORDER BY "tb1"."date" ASC) "r"
   , "tb2"."opcode"
   , "tb1"."innerid"
   , "tb1"."date"
   , From_iso8601_timestamp(tb1.date) as "real_date"
   , "tb2"."eventtype"
   , "tb1"."fuelused"
   , "tb1"."mileage"
   , "tb1"."latitude"
   , "tb1"."longitude"
   FROM
     rt_message_header tb1
   , rt_messages tb2
   WHERE ((("tb1"."uuid" = "tb2"."header_uuid") AND ("tb2"."opcode" = '39')) AND ("tb2"."type" = 'event'))
   ORDER BY "tb1"."innerid" ASC, "tb1"."date" ASC
)

它給了我以下錯誤:

您的查詢有以下錯誤:不支持的 Hive 類型:帶時區的時間戳

但是,當我自己運行查詢時,它可以正常工作,並且 From_iso8601_timestamp 在這里被提及為有效的日期函數。

誰能告訴我我做錯了什么?

不幸的是,Athena 並不完全支持所有 Presto 功能,它有局限性,並且在技術上落后於 Presto 幾個版本。 有一些嘗試使 Athena 與 AWS Glue Metastore 緊密集成,雖然基於 Hive 的 Metastore 有一些不一致之處。 我希望 Spark、Hive、Glue、Athena、Presto 等能夠與同一個元存儲一起工作,這會讓生活更輕松,但回到你的問題:

這份關於 Presto 的舊 teradata 分支的文檔提到了 presto 中時間戳的一些問題:

Presto 聲明帶/不帶時區的時間戳的方法不是 sql 標准。 在 Presto 中,兩者都使用單詞 TIMESTAMP 聲明,例如 TIMESTAMP '2003-12-10 10:32:02.1212' 或 TIMESTAMP '2003-12-10 10:32:02.1212 UTC'。 根據您是否在時間戳末尾包含時區來確定時間戳是否帶有時區。 在其他系統中,時間戳被顯式聲明為 TIMESTAMP WITH TIME ZONE 或 TIMESTAMP WITHOUT TIME ZONE

Athena 從中分叉的 Presto 版本確實支持timestamptimestamp with timezone的時間戳,但具有 teradata 文檔中提到的那個怪癖,這應該不是問題。 真正的問題是Athena 不支持 timestamp with timezone

您鏈接到的 presto 文檔顯示該函數返回timestamp with timezone類型的值,因此您需要將其轉換為受支持的其他內容。 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 ,但由於某些內部不一致的原因,您無法創建視圖並且會出現錯誤。

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

無論出於何種原因,創建視圖都需要 java 類,而解析 select 中的值則不需要。 這是一個應該解決的錯誤。

這行得通

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"
)

您可以在 Athena over Timestamp 數據類型 (dt) 中使用以下語法:

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

在我最近正在做的事情上遇到了類似的事情。 AWS Support 向我指出了 Davos 解決方案,但它最終對我的情況不起作用。 最終對我有用的解決方案是:

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

希望有幫助!

select 
cast(replace(cast(at_timezone(<YOUR_DATE_FIELD> , 'US/Eastern') as varchar) ,'America/New_York', '') as timestamp),
typeof(cast(replace(cast(at_timezone(<YOUR_DATE_FIELD> , 'US/Eastern') as varchar) ,'America/New_York', '') as timestamp))
from 
<YOUR_TABLE>

可以說 <YOUR_DATE_FIELD> 是 UTC 。 第一個 at_timezone 函數會將日期更改為 EST 格式,但會附加額外的文字“US/Eastern”。

下一步是將其轉換為 varchar 以刪除文字。 但是,當轉換為 varchar 時,它會更改為 'America/New_York',這需要替換為 ''。 最后將其轉換為時間戳

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM