如何解决在 Athena 中查询表时出现的“FAILED: NullPointerException Name is null” 错误?
当我查询 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 命令。然后,完成以下步骤以更新此命令的输出:
-
在表上运行与以下示例类似的命令:
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" } }
-
在输出中,删除 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" -
将 "TableType": "EXTERNAL_TABLE" 参数添加到输出。
-
将输出用作 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 中表的属性,请完成以下步骤:
- 打开 AWS Glue 控制台。
- 在导航窗格的 Data Catalog(数据目录)下,选择 Tables(表)。
- 选择要更新的表。
- 选择 Action(操作),然后选择 Edit table(编辑表)。
- 在 SerDe parameters(SerDe 参数)部分中,选择 Add(添加)。
- 对于 Key(键),输入“serialization.format”,对于 Value(值)输入“1”。
- 选择保存。
使用 AWS CLI 更新表
要更新表的 SerDeInfo 参数,请运行 update-table AWS CLI 命令。要运行此命令,必须具备定义整个表架构的 TableInput 对象。
要获取表的 TableInput 对象,请运行 get-table AWS CLI 命令。然后,更新此命令的输出以加入 SerDeInfo 参数。