如何解决当我在 Amazon Athena 中查询表时遇到的“FAILED: NullPointerException Name is null”错误?

3 分钟阅读
0

当我查询 Amazon Athena 表时,我收到了“FAILED: NullPointerException Name is Null”(失败:NullPointerException 名称为空)错误。

简短描述

如果没有为 AWS Glue 数据目录中查询的表定义属性 TableType,则会出现此错误。TableType 属性用于定义表属于外部表还是视图。可用于定义此属性的值例如 EXTERNAL_TABLE 和 VIRTUAL_VIEW。如果要运行 DDL 查询,例如“SHOW CREATE TABLE”或“MSCK REPAIR TABLE”,则必须定义 TableType 属性。

如果您使用 AWS CloudFormation 模板或 AWS Glue API 定义了表,但未将 TableType 指定为其中的一个属性,则可能会遇到此错误。

解决方法

要解决此错误,请根据您的使用场景执行以下一种或多种解决方法:

在创建表时添加属性

创建表时添加 TableType 属性。

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

更新 CloudFormation 模板或 AWS Glue API 调用

如果您使用 CloudFormation 模板或 AWS Glue API 定义了表但未指定 TableType 属性,则更新 CloudFormation 模板或 AWS Glue API 调用以添加 TableType 属性。

使用 AWS 命令行界面(AWS CLI)更新表

要更新表的 TableType 属性,请使用 AWS CLI 命令 aws glue update-table。要运行此命令,您必须拥有定义整个表体系结构的 TableInput 对象。

要获取表的 TableInput 对象,请运行 aws glue get-table 命令。然后,按照以下步骤中的定义更新此命令的输出。

注意:如果在运行 AWS CLI 命令时遇到错误,请确保您使用的是最新版本的 AWS CLI

1.    对您的表运行与以下类似的命令:

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

2.    您会收到与以下类似的输出:

{
    "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"
    }
}

3.    从上面的输出中移除参数,例如 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

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

5.    将输出作为 TableInput 参数来运行 update-table 命令。

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 替换为您的账户 ID
  • s3://doc_example_bucket/doc_example_prefix/ 替换为您用于存储该表的 Amazon Simple Storage Service(Amazon S3)位置

运行上面的命令后,TableType 参数会更新,并且 DDL 查询(例如 SHOW CREATE TABLE 或 MSCK REPAIR TABLE)也会成功。


相关信息

排查 Athena 中的问题

AWS 官方
AWS 官方已更新 3 年前