选择正确的 SerDe、本机 JSON SerDe、
org.apache.hive.hcatalog.data.JsonSerDe
或 OpenX SerDe、
org.openx.data.jsonserde.JsonSerDe
。有关更多信息,请参阅
JSON SerDe 库
。
确保每个 JSON 编码的记录表示在单独的行上,而不是采用美观的打印格式。
SerDe 期望每个 JSON 文档都位于单行文本中,并且不使用行终止字符分隔记录中的字段。如果 JSON 文本采用美观的打印格式,当您在创建表后尝试对其进行查询时,可能会收到类似以下内容的错误消息:
HIVE_CURSOR_ERROR: Row is not a valid JSON Object
(HIVE_CURSOR_ERROR:行不是有效的 JSON 对象)或
HIVE_CURSOR_ERROR: JsonParseException: Unexpected end-of-input: expected close marker for OBJECT
(HIVE_CURSOR_ERROR:JsonParseException:意外的输入结束:对象的预期关闭标记)。有关更多信息,请参阅 GitHub 上 OpenX SerDe 文档中的
JSON 数据文件
。
在不区分大小写的列中生成 JSON 编码的数据。
提供用于忽略格式错误的记录的选项,如本示例中所示。
CREATE EXTERNAL TABLE json_table (
column_a string,
column_b int
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES ('ignore.malformed.json' = 'true')
LOCATION 's3://DOC-EXAMPLE-BUCKET/path/';
将源数据中具有待定架构的字段转换为 Athena 中的 JSON 编码字符串。
当 Athena 创建由 JSON 数据提供支持的表时,它会基于现有的和预定义的架构解析数据。但并非您的所有数据都可能具有预定义的架构。要在这种情况下简化架构管理,通常有用的做法是将源数据中具有不确定架构的字段转换为 Athena 中的 JSON 字符串,然后使用 JSON SerDe 库。
例如,请考虑一个从不同传感器发布具有公共字段的事件的 IoT 应用程序。其中一个字段必须存储一个对发送事件的传感器唯一的自定义有效负载。在这种情况下,因为您不知道架构,我们建议您将信息存储为 JSON 编码的字符串。为此,请将 Athena 表中的数据转换为 JSON,如下例所示。您还可以将 JSON 编码的数据转换为 Athena 数据类型。
CAST('HELLO ATHENA' AS JSON) AS hello_msg,
CAST(12345 AS JSON) AS some_int,
CAST(MAP(ARRAY['a', 'b'], ARRAY[1,2]) AS JSON) AS some_map
SELECT * FROM dataset
此查询返回:
+-------------------------------------------+
| hello_msg | some_int | some_map |
+-------------------------------------------+
| "HELLO ATHENA" | 12345 |
{
"a":1,"b":2} |
+-------------------------------------------+
将 JSON 转换为 Athena 数据类型
要将 JSON 数据转换为 Athena 数据类型,请使用
CAST
。
在本示例中,为将字符串表示为 JSON 编码,一开始就使用
JSON
关键字并使用单引号,例如
JSON
'12345'
WITH dataset AS (
SELECT
CAST(JSON '"HELLO ATHENA"' AS VARCHAR) AS hello_msg,
CAST(JSON '12345' AS INTEGER) AS some_int,
CAST(JSON '{"a":1,"b":2}' AS MAP(VARCHAR, INTEGER)) AS some_map
SELECT * FROM dataset
此查询返回: