如何从AWS Athena获取JSON格式的结果?

dgsult0t  于 2023-02-20  发布在  其他
关注(0)|答案(1)|浏览(134)

我想得到JSON格式的结果,下面是objectobj的结构

UUID              string 
MobileCountryCode string 
UserState         []struct {
    Mobile    int64 
    IsNewUser bool  
}

当我通过Redash从Athena中简单选择对象时:

select obj FROM table_name

获取此格式的输出:

{uuid=UCLPKJWPZXH,mobile_country_code=,user_state=[{mobile=9988998899, is_new_user=false}]}

我们可以清楚地看到,输出中的json键不包含双引号,而是用=代替:以限定正确的json
我甚至试着把它投给json:

select CAST(obj AS JSON) AS json_obj FROM table_name

但是我只得到没有json键的值,如下所示:

["UCLPKJWPZXH","",[["9988998899",false]]]

但我希望它是这样的与json键

{"uuid":"UCLPKJWPZXH","mobile_country_code":"","user_state":[{"mobile":9988998899,"is_new_user":false}]}
v6ylcynt

v6ylcynt1#

Athena基于Presto/Trino(引擎v3应使用Trino函数),在Trino中cast(... as json)应工作:

select cast(r as json)
from (values (1, CAST(ROW('UUID123', array[row(1, TRUE)]) AS ROW(UUID varchar, UserState array(row(Mobile int, IsNewUser boolean)))))) as t(id, r);

输出:

_col0
----------------------------------------------------------------
 {"uuid":"UUID123","userstate":[{"mobile":1,"isnewuser":true}]}

尝试升级到v3引擎。如果您已经在使用v3引擎,或者升级后它不工作,或者您无法升级-唯一的方法是将ROW转换为MAP,因为Presto将ROW视为数组(docs):
当从ROW转换为JSON时,结果是JSON数组而不是JSON对象,这是因为在SQL中位置比行的名称更重要。
将行转换为Map可能非常麻烦:

select cast(
               map(array['UUID123', 'MobileCountryCode', 'UserState'],
                   array[
                        cast(r.UUID as json),
                        cast(r.MobileCountryCode as json),
                        cast(
                            transform(r.UserState,
                                e -> map(
                                    array['Mobile', 'IsNewUser'],
                                    array[cast(e.Mobile as json), cast(e.IsNewUser as json)]))
                            as json)
                        ])
           as json)
from (values (1, CAST(ROW('UUID123', 'US', array[row(1, TRUE)]) AS ROW (UUID varchar, MobileCountryCode varchar,
                                                                        UserState array(row(Mobile int, IsNewUser boolean)))))) as t(id, r);

输出:

_col0
--------------------------------------------------------------------------------------------
 {"MobileCountryCode":"US","UUID123":"UUID123","UserState":[{"IsNewUser":true,"Mobile":1}]}

相关问题