Skip to content

如何解决在 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_TABLEVIRTUAL_VIEW 之类的值来定义该属性。

要运行 DDL 查询,例如 SHOW CREATE TABLEMSCK 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 参数。调用 CreateTableUpdateTable 操作时,请将 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. 在输出中,删除 UpdateTimeIsRegisteredWithLakeFormationCreatedByDatabaseNameCreateTime 参数。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 调用创建或更新表时,请在 TableInputStorageDescriptor 中加入 SerDeInfo 参数。将 SerDeInfoParameters(参数)字段设置为 {"serialization.format": "1"}。

此参数用于调用 CreateTableUpdateTable 等操作。有关详细信息,请参阅 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 官方已更新 8 个月前