解串器在 Athena 中不存在错误

问题描述

我在尝试创建固定宽度表格时遇到此错误。 前 7 个占位符用于第一列,后跟一个空格,然后是从第 9 位开始的第二列。

  1 1050174
  1 1050175
  1 1050177
  1 1050178
  2 1050180
  2 1050181
  1 1050187
  1 1050188
  1 1050189

我收到此错误

HIVE_SERDE_NOT_FOUND:解串器不存在: org.apache.hadoop.hive.contrib.serde2.regexserde

这个create table语句不会失败,而是在选择数据时显示上面提到的错误

CREATE EXTERNAL TABLE IF NOT EXISTS hunspell.frequency1(
  `count` string,`word` string 
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.regexserde' 
WITH SERDEPROPERTIES ("input.regex" = "(.{7})(.{100})" ) LOCATION 's3://hunspell/frequency/'

更新:

此测试表按预期工作。它提取第一、第二第五列。

CREATE EXTERNAL TABLE hunspell.citiesr1 (id int,city_org string,ppl float) 
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.regexserde' 
WITH SERDEPROPERTIES ('input.regex'='^(\\d+)\\t([^\\t]*)\\t\\S+\\t\\S+\\t(\\d++.\\d++).*') LOCATION 's3://hunspell/myserde/';

数据如下:

1   東京  Tokyo   Japan   33.8
2   大阪  Osaka   Japan   16.7
11  北京  Beijing China   13.2
12  廣州  Guangzhou   China   15.3
21  Αθηνα   athens  Greece  3.7
31  Якутск  Yakutsk Russia  0.6
110 La Coruña   Corunna Spain   0.37
112 Cádiz   Cadiz   Spain   0.4
120 Köln    Cologne Germany 0.97
121 München Munich  Germany 1.2
130 Tårnby  Tarnby  Danmark 0.04
140 Tønsberg    Tonsberg    norway  0.05
150 Besançon    Bisanz  France  0.12

上面发布的示例数据使用制表符作为分隔符。我的文件不是由制表符分隔的。假设前 4 个字符是频率,接下来的 10 个字符是 ID,后面可能跟也可能不跟 100 个字符的名称

  1 1050174
  1 1050175
  1 1050177

换句话说,我如何使用正则表达式 serde 在 Athena 中导入固定宽度的数据?


更新 2:

感谢回答,我可以使用这个导入数据:

CREATE EXTERNAL TABLE `frequency`(
  `count` string,`word` string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.regexserde' 
WITH SERDEPROPERTIES ('input.regex'='^(.{7}) (.+)$')
LOCATION 's3://XunspellX/stack/';

是否可以将第一列“计数”为整数?如果我只是将第一列类型更改为整数,Athena 不会导入任何内容

解决方法

您在问题的第一部分收到错误消息,因为您使用的是 Athena 不支持的 SerDe。

HIVE_SERDE_NOT_FOUND:反序列化器不存在:org.apache.hadoop.hive.contrib.serde2.RegexSerDe

Athena docs 列出了支持的 SerDes,因此对于正则表达式,您将使用 org.apache.hadoop.hive.serde2.RegexSerDe,正如您稍后发现的那样。


对于基于长度解析列,您应该能够根据需要修改您的正则表达式模式。以下是基于您提供的示例数据和描述的一些不同示例。

场景 1

两个以空格分隔的数字列,可能带有前导和/或尾随空格。

  1 1050174
  1 1050175
  1 1050177

模式/^ *(\d+) (\d+) *$/gm

场景 2

前 7 个占位符用于第一列,后跟一个空格 然后是从第 9 位开始的第二列

0000001 105017434786
0000002 105013
0000003 1050177438

模式/^(\d{7}) (\d+)$/gm

场景 3

我的文件不是由制表符分隔的。让我们假设前 4 个字符 是频率,接下来的 10 个是 ID,后面可能跟着也可能不跟着 100个字符的名称

假设在这种情况下,您的数据不像其他两个示例那样由空格分隔,并且第三列可以为空且最大长度为 100,您可能会得到如下结果:

00201050174347some-nullable-third-column-value
01931050174348
19841050174349another-nullable-third-column-value

模式/^(\d{4})(\d{10})(.{0,100})$/gm

最后,将所有内容放在一起,您将有一个 create table 语句,对于第三种情况,它看起来像这样:

CREATE EXTERNAL TABLE sample_database.sample_data (frequency int,id bigint,description varchar(100)) 
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe' 
WITH SERDEPROPERTIES ('input.regex'='^(\\d{4})(\\d{10})(.{0,100})$')
LOCATION 's3://your-s3-bucket/';

请注意此处正则表达式模式中的双反斜杠。每this doc

注意:RegexSerDe 遵循 Java 标准。因为反斜杠是 Java String 类中的转义字符,所以必须使用双反斜杠来定义单反斜杠。例如,要定义 \w,您必须在正则表达式中使用 \w。

,

根据用户fearerjon 的建议,以下查询按预期工作:

CREATE EXTERNAL TABLE `frequency`(
  `count` int,`word` string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe' 
WITH SERDEPROPERTIES ('input.regex'='^ *(\\d+) (.+)$')
LOCATION 's3://XunspelX/stack/';