首页 > 解决方案 > Hive 外部表将 json 读取为文本文件

问题描述

我正在尝试为 .txt 格式的 json 文件创建一个配置单元外部表。我尝试了几种方法,但我认为应该如何定义配置单元外部表我错了:

我的示例 JSON 是:

[[
{
    "user": "ron",
    "id": "17110",
    "addr": "Some address"
},
{
    "user": "harry",
    "id": "42230",
    "addr": "some other address"


}]]

如您所见,它是数组中的数组。似乎这是由 API 返回的有效 json,尽管我读过帖子说 json 应该以“{”开头

无论如何,我正在尝试创建一个像这样的外部表:

    CREATE EXTERNAL TABLE db1.user(
    array<array<
    user:string,
    id:string,
    desc:string
    >>)
  PARTITIONED  BY(date string)
  ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
  STORED AS TEXTFILE
  LOCATION '/tmp/data/addr'

这不起作用。这样的事情也不起作用

CREATE EXTERNAL TABLE db1.user(
    user string,
    id string,
    desc string

 )PARTITIONED  BY(date string)
  ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
  STORED AS TEXTFILE
  LOCATION '/tmp/data/addr'

在尝试修改 json 文本文件,将 [ 替换为 { 等,添加分区后,我仍然无法使用 select * 查询它。我缺少表结构中的一个关键部分。

你能帮助我,以便表格可以正确读取我的 JSON 吗?

如果需要,我可以修改输入 JSON,如果双 [[ 有问题。

标签: jsonhivecreate-tablehive-serdehiveddl

解决方案


第一个:表中的行应该在文件中表示为单行,而不是多行 JSON。

第二:您可以将array<some complex type>其作为单列,但这并不方便,因为您需要分解数组才能访问嵌套元素。您可能需要这种结构的唯一原因是当确实有多行带有array<array<>>.

第三: [] 中的所有内容都是一个数组。{} 中的所有内容都是一个结构或映射,在您的情况下它是一个结构,您错过了这条规则。Fields user, idanddesc都在 struct 里面,而 struct 嵌套在数组里面。数组在其定义中只能有类型,如果是嵌套结构,则为array<struct<...>>,如果数组为简单类型,例如array<string>

第四:您的 JSON 无效,因为它在地址值后包含额外的逗号,请修复它。

colname如果您更喜欢包含单列,array<array<struct<...>>>则创建如下表:

CREATE EXTERNAL TABLE db1.user(
    colname array<array<
    struct<user:string,
    id:string,
    desc:string>
    >>)...

JSON 文件应如下所示(每行一行):

[[{"user": "ron","id": "17110","addr": "Some address"}, {"user": "harry","id": "42230","addr": "some other address"}]]

如果文件包含嵌套在另一个数组中的单个大数组,最好删除 [[ 和 ]],删除结构之间的逗号和结构内的额外换行符。如果单行是 struct {},您可以在没有上层 struct<> 的情况下定义表,只有嵌套结构应定义为 struct<>:

CREATE EXTERNAL TABLE db1.user(
    user string,
    id   string,
    desc string
   )...

请注意,在这种情况下,您不需要:在列名和类型之间。:仅在嵌套结构内使用。JSON 应该看起来像这样(在 DDL 中定义的整个 JSON 对象在一行中,结构之间没有逗号,每个结构在单独的行中):

{"user": "ron","id": "17110","addr": "Some address"}
{"user": "harry","id": "42230","addr": "some other address"}

希望你知道它是如何工作的。在JSONSerDe手册中阅读更多内容。


推荐阅读