web-dev-qa-db-ja.com

アテナでタイムゾーン付きのタイムスタンプへの変換に失敗しました

私は次のビューに作成しようとしています:

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
)

そして、それは私に次のエラーを与えます:

クエリには次のエラーがあります:サポートされていないハイブタイプ:タイムゾーン付きのタイムスタンプ

ただし、それ自体でクエリを実行すると正常に動作し、From_iso8601_timestampが有効な日付関数として here に言及されています。

誰が私が間違っているのか教えてもらえますか?

6
Gal Itzhak

残念ながら、AthenaはPrestoのすべての機能を完全にサポートしているわけではありません。 limitations を持ち、技術的にはPrestoのいくつかのバージョンです。 AthenaをAWS Glueメタストアと密接に統合しようとする試みがいくつかありますが、Hiveのメタストアには基づいていますが、いくつかの矛盾があります。 Spark、Hive、Glue、Athena、Prestoなどが同じメタストアで動作することを願っています。

この Prestoの古いテラデータフォークに関するドキュメント は、prestoのタイムスタンプに関するいくつかの問題に言及しています。

タイムゾーンの有無にかかわらずタイムスタンプを宣言するPrestoの方法は、SQL標準ではありません。 Prestoでは、両方ともWord 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のバージョンは、timestampと_timestamp with timezone_の両方をサポートしますが、テラデータのドキュメントで言及されているように、問題ではないという癖があります。本当の問題は、 Athenaはタイムゾーン付きのタイムスタンプをサポートしていません です。

リンクした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エラー[失敗]: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エラー[失敗]:クラス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"
)
_
9
Davos

Athena over Timestampデータ型(dt)で次の構文を使用できます。

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

私が最近取り組んでいたもので似たようなものに走りました。 AWSサポートは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

お役に立てば幸いです!

1
Andrew Madsen