【问题标题】:AWS Athena: "HIVE_BAD_DATA: Error parsing column 'X' : empty String"AWS Athena:“HIVE_BAD_DATA:解析列 'X' 时出错:空字符串”
【发布时间】:2020-05-20 10:14:53
【问题描述】:

我想使用 OpenCSVSerde 基于 CSV 文件在 AWS Athena 上创建一个外部表。

CREATE EXTERNAL TABLE `table`(name string, value double, group string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' 
WITH SERDEPROPERTIES ("separatorChar" = ",", "escapeChar" = "\\","skip.header.line.count"="1",  "serialization.null.format"="") 
LOCATION 's3://path' ; 

该文件包含“值”字段(双精度类型)的一些缺失值。它看起来像这样:

name,value,group    
name1,0.5,a
name2,0.2,a
name3,,a
name4,0.11,b

创建它之后,当我尝试运行一些查询(比如简单的“从表中选择 *”)时,Athena 给出了这个错误:

HIVE_BAD_DATA: Error parsing column '1': empty String

正如您从创建外部表查询中看到的那样,我尝试添加 'serialization.null.format'='' 但它似乎不起作用。我找到的唯一解决方案是将列“值”定义为字符串,但这显然不是理想的解决方案(尤其是如果您有很多这样的列)。

你知道如何解决这个问题吗?

谢谢

【问题讨论】:

  • 这是OpenCSVSerDe 对非STRING 数据类型的限制,每个documentation,您可以尝试使用LazySimpleSerDe 吗?
  • 它确实有效,谢谢!我想使用 OpenCSVSerde 轻松处理我拥有的一些双引号值......但如果有这个限制,我想我必须选择较小的邪恶:)

标签: amazon-web-services hive amazon-athena


【解决方案1】:

正如 Vamsi Prabhala 提到 OpenCSVSerde 根本不支持这一点,来自 documentation

解析器无法识别定义为数值数据类型的列中的空值或空值,而将它们保留为 STRING 的默认数据类型。解决方法是将列声明为 STRING,然后在 SELECT 查询或视图中对其进行 CAST。

因此,如果您确实想坚持使用 OpenCSVSerde,请像以前一样创建表("serialization.null.format"="" 不起作用):

CREATE EXTERNAL TABLE `table`(
    name string,
    value double,
    group string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' 
WITH SERDEPROPERTIES (
    "separatorChar" = ",",
    "escapeChar" = "\\",
    "skip.header.line.count"="1") 
LOCATION 's3://path'; 

然后创建一个视图为:

CREATE VIEW "typed_table" AS
SELECT
"name",
CAST(
    "value" CASE
        "value"
        WHEN '' THEN NULL
        ELSE "value"
    END AS DOUBLE
),
"group"
FROM "table";

【讨论】:

    【解决方案2】:

    这里有几点需要注意。

    1. 在 Athena 中创建表格时(例如从 CSV),您需要确保表格标题不会出现。如果您注意到第 1 行有表头,这很可能是出现 HIVE_BAD_DATA 错误的原因。 您只需添加表格属性即可忽略标题

      TBLPROPERTIES("skip.header.line.count"="1")

    例如。

    CREATE EXTERNAL TABLE `table`(name string, value double, group string)
    ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' 
    WITH SERDEPROPERTIES ("separatorChar" = ",", "escapeChar" = "\\","skip.header.line.count"="1",  "serialization.null.format"="") 
    LOCATION 's3://path' 
    TBLPROPERTIES("skip.header.line.count"="1");
    

    或者,如果表已经创建,您可以使用更改表

    ALTER TABLE table_name SET TBLPROPERTIES ("skip.header.line.count"="1)
    
    1. 在查询表时,您可能必须将字符串解析为所需的 data_type。你可以通过使用 cast 甚至 date_parse 例如。

      SELECT * FROM table_name order by date_parse(field,'%d/%m/%Y') desc limit 100;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      • 1970-01-01
      • 2023-02-23
      • 1970-01-01
      • 1970-01-01
      • 2012-10-04
      相关资源
      最近更新 更多