跳至内容

如何解决在 Athena 中查询表时出现的“FAILED: NullPointerException Name is null” 错误?

4 分钟阅读
0

当我查询 Amazon Athena 表时,收到“FAILED: NullPointerException Name is Null”错误。

简短描述

您可能收到的以下错误消息属于 FAILED: NullPointerException 错误类型。

NullPointerException Name is null

如果没有为 AWS Glue Data Catalog 中查询的表定义 TableType 属性,就会出现此错误。TableType 属性可定义该表是外部表还是视图。可以使用诸如 EXTERNAL_TABLE 和 VIRTUAL_VIEW 之类的值来定义该属性。

要运行 DDL 查询,例如 SHOW CREATE TABLE 或 MSCK REPAIR TABLE,必须定义 TableType 属性。

使用 AWS CloudFormation 模板或 AWS Glue API 且未指定 TableType 属性时,也可能出现此错误。

java.lang.NullPointerException: Cannot invoke "java.util.Map.entrySet()" because the return value of "org.apache.hadoop.hive.metastore.api.SerDeInfo.getParameters()" is null

如果没有为 Data Catalog 中查询的表定义 SerDeInfo 参数,就会出现此错误。SerDeInfo 参数是定义 SerDe 初始化参数的键值对。您可以使用值 "serialization.format": "1" 来定义该属性。要运行 DDL 查询,例如 SHOW CREATE TABLE,必须定义 SerDeInfo 属性参数。

使用 CloudFormation 模板或 AWS Glue API 且未指定 SerDeInfo 属性时,也可能会出现该错误。

解决方法

完成最适合您收到的错误消息的故障排除步骤。

**注意:**如果在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,确保您使用的是最新版本的 AWS CLI。

NullPointerException Name is null

要解决此错误,请根据您的用例完成以下一项或多项操作。

在创建表时添加属性

创建表格时,请添加 TableType 属性。

**注意:**创建表时如果使用的是 DDL 语句或 AWS Glue 爬网程序,则会自动定义 TableType 属性。

更新 CloudFormation 模板

使用 CloudFormation 模板创建 AWS Glue 表时,请在 AWS Glue 表资源的 TableInput 属性中指定 TableType 属性。将 TableType 设置为“EXTERNAL_TABLE”。有关详细信息,请参阅 AWS::Glue::Table TableInput。

更新 AWS Glue API 调用

使用 AWS Glue API 调用创建或更新表时,请确保在 TableInput 属性中包含 TableType 参数。调用 CreateTable 或 UpdateTable 操作时,请将 TableType 参数设置为“EXTERNAL_TABLE”。

使用 AWS CLI 更新表

要更新表的 TableType 属性,请运行 update-table AWS CLI 命令。要运行此命令,必须具备定义整个表架构的 TableInput 对象。

要获取表的 TableInput 对象,请运行 get-table AWS CLI 命令。然后,完成以下步骤以更新此命令的输出:

  1. 在表上运行与以下示例类似的命令:

    aws glue get-table --catalog-id 1111222233334444 --database doc_example_database --name doc_example_table

    输出示例:

    {    "Table": {            "StorageDescriptor": {
                "OutputFormat": "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat",
                "SortColumns": [],
                "InputFormat": "org.apache.hadoop.mapred.TextInputFormat",
                "SerdeInfo": {
                        "SerializationLibrary": "org.apache.hadoop.hive.serde2.OpenCSVSerde",
                        "Parameters": {
                        "serialization.format": "1"
                            }
                },
                "Parameters": {
                    "separatorChar": ","
                },
                "Location": "s3://doc_example_bucket/doc_example_prefix/",
                "NumberOfBuckets": 0,
                "StoredAsSubDirectories": false,
                "Columns": [
                    {
                        "Type": "int",
                        "Name": "id"
                    },
                    {
                        "Type": "string",
                        "Name": "name"
                    }
                ],
                "Compressed": false
            },
            "UpdateTime": 1620508098.0,
            "IsRegisteredWithLakeFormation": false,
            "Name": "doc_example_table",
            "CreatedBy": "arn:aws:iam::1111222233334444:user/Administrator",
            "DatabaseName": "doc_example_database",
            "Owner": "1111222233334444",
            "Retention": 0,
            "CreateTime": 1619909955.0,
            "Description": "tb description"
        }
    }
  2. 在输出中,删除 UpdateTime、IsRegisteredWithLakeFormation、CreatedBy、DatabaseName 和 CreateTime 参数。AWS Glue 不支持这些参数。
    如果在运行 update-table 命令时在 TableInput 属性中加入这些参数,则可能会出现以下错误:

    "Parameter validation failed:Unknown parameter in TableInput: "UpdateTime", must be one of: Name, Description, Owner, LastAccessTime, LastAnalyzedTime, Retention, StorageDescriptor, PartitionKeys, ViewOriginalText, ViewExpandedText, TableType, Parameters"
    "Unknown parameter in TableInput: "IsRegisteredWithLakeFormation", must be one of: Name, Description, Owner, LastAccessTime, LastAnalyzedTime, Retention, StorageDescriptor, PartitionKeys, ViewOriginalText, ViewExpandedText, TableType, Parameters"
    "Unknown parameter in TableInput: "CreatedBy", must be one of: Name, Description, Owner, LastAccessTime, LastAnalyzedTime, Retention, StorageDescriptor, PartitionKeys, ViewOriginalText, ViewExpandedText, TableType, Parameters"
    "Unknown parameter in TableInput: "DatabaseName", must be one of: Name, Description, Owner, LastAccessTime, LastAnalyzedTime, Retention, StorageDescriptor, PartitionKeys, ViewOriginalText, ViewExpandedText, TableType, Parameters"
    "Unknown parameter in TableInput: "CreateTime", must be one of: Name, Description, Owner, LastAccessTime, LastAnalyzedTime, Retention, StorageDescriptor, PartitionKeys, ViewOriginalText, ViewExpandedText, TableType, Parameters"

  3. 将 "TableType": "EXTERNAL_TABLE" 参数添加到输出。

  4. 将输出用作 TableInput 参数来运行以下命令:

    aws glue update-table --catalog-id 1111222233334444 --database-name doc_example_database --table-input '{        "StorageDescriptor": {            "OutputFormat": "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat",
                "SortColumns": [],
                "InputFormat": "org.apache.hadoop.mapred.TextInputFormat",
                "SerdeInfo": {
                    "SerializationLibrary": "org.apache.hadoop.hive.serde2.OpenCSVSerde",
                    "Parameters": {
                        "serialization.format":"1"
                    }
                },
                "Parameters": {
                    "separatorChar":","
                },
                "Location": "s3://doc_example_bucket/doc_example_prefix/",
                "NumberOfBuckets": 0,
                "StoredAsSubDirectories": false,
                "Columns": [
                    {
                        "Type": "int",
                        "Name": "id"
                    },
                    {
                        "Type": "string",
                        "Name": "name"
                    }
                ],
                "Compressed": false
            },
            "Name": "doc_example_table",
            "TableType": "EXTERNAL_TABLE",
            "Owner": "1111222233334444",
            "Retention": 0,
            "Description": "tb description"
        }'

    **注意:**替换以下变量:
    将 doc_example_database 替换为您的数据库名称
    将 doc_example_table 替换为您的表名
    将 1111222233334444 替换为您的 AWS 账户 ID
    将 s3://doc_example_bucket/doc_example_prefix/ 替换为存储表所在的 Amazon Simple Storage Service (Amazon S3) 位置
    运行上述命令后,TableType 参数会更新,DDL 查询成功。

java.lang.NullPointerException: Cannot invoke "java.util.Map.entrySet()" because the return value of "org.apache.hadoop.hive.metastore.api.SerDeInfo.getParameters()" is null

要解决此错误,请根据您的用例完成以下一项或多项操作。

在创建表时添加 SerDeInfo 参数

创建表时,请添加 SerDeInfo 参数,例如 "serialization.format": "1", "field.delim":","。

更新 CloudFormation 模板

使用 CloudFormation 模板创建 AWS Glue 表时,请指定 SerDeInfo 参数。在 Glue 表资源的 TableInput 部分中,导航到 StorageDescriptor。选择 SerDeInfo,然后选择 Parameters(参数)。添加 {"serialization.format": "1"} 作为参数。

有关详细信息,请参阅 AWS::Glue::Table SerdeInfo。

更新 AWS Glue API 调用

使用 AWS Glue API 调用创建或更新表时,请在 TableInput 的 StorageDescriptor 中加入 SerDeInfo 参数。将 SerDeInfo 的 Parameters(参数)字段设置为 {"serialization.format": "1"}。

此参数用于调用 CreateTable 或 UpdateTable 等操作。有关详细信息,请参阅 StorageDescriptor 结构。

使用 AWS Glue 控制台更新表

要更新 Data Catalog 中表的属性,请完成以下步骤:

  1. 打开 AWS Glue 控制台。
  2. 在导航窗格的 Data Catalog(数据目录)下,选择 Tables(表)。
  3. 选择要更新的表。
  4. 选择 Action(操作),然后选择 Edit table(编辑表)。
  5. 在 SerDe parameters(SerDe 参数)部分中,选择 Add(添加)。
  6. 对于 Key(键),输入“serialization.format”,对于 Value(值)输入“1”。
  7. 选择保存。

使用 AWS CLI 更新表

要更新表的 SerDeInfo 参数,请运行 update-table AWS CLI 命令。要运行此命令,必须具备定义整个表架构的 TableInput 对象。

要获取表的 TableInput 对象,请运行 get-table AWS CLI 命令。然后,更新此命令的输出以加入 SerDeInfo 参数。

相关信息

解决 Athena 中的问题

AWS 官方已更新 2 年前