Java查询DynamoDB表报键与schema不匹配错误如何解决?
问题根因
- 首先违反了DynamoDB
GetItem接口的主键约束:GetItem请求的key参数只能传入表定义的主键属性,不能包含非主键字段。你当前表的主键是分区键envName、排序键configurationName,但你构建查询key的时候额外加入了非主键的status字段,直接触发了schema不匹配的报错。 - 客户端调用顺序错误:main方法中你先关闭了DynamoDB客户端,再调用查询逻辑,会导致后续请求使用已销毁的客户端,即使主键问题修复也无法正常请求。
- 存在两处小语法/逻辑缺陷:方法参数末尾多了多余的逗号,查询无结果时的格式化输出语句没有传入对应占位符的参数,运行时会抛出异常。
修复后的代码示例
package com.dev.newlibs; // 相关import保持不变 public class updatenewCMDB { public static void main(String[] args)throws Exception { String tableName = "env_dashboard"; String configurationName = "component"; String configurationNameValue = "ec2"; String envName = "env_Name"; String envNameValue = "dev"; String status = "status"; String statusValue = "COMPLETE"; DynamoDbClient client = DynamoDbClient.builder() .region(Region.EU_WEST_1) .build(); // 先执行业务逻辑,最后再关闭客户端 updateEnvDashboard(client, tableName, configurationName, configurationNameValue, envName, envNameValue, status, statusValue); client.close(); } public static void updateEnvDashboard(DynamoDbClient client, String tableName, String configurationName, String configurationNameValue, String envName, String envNameValue, String status, String statusValue) throws Exception { // 删除末尾多余逗号 // GetItem的key只保留主键属性 HashMap<String,AttributeValue> itemToGet = new HashMap<String,AttributeValue>(); itemToGet.put(envName, AttributeValue.builder().s(envNameValue).build()); itemToGet.put(configurationName, AttributeValue.builder().s(configurationNameValue).build()); // 移除非主键的status字段,status是普通属性不能出现在GetItem的key里 GetItemRequest request = GetItemRequest.builder() .key(itemToGet) .tableName(tableName) .build(); try { Map<String,AttributeValue> returnedItem = client.getItem(request).item(); if (returnedItem != null) { // 可以在这里加status校验逻辑,判断返回的条目status是否符合要求 if(statusValue.equals(returnedItem.get(status).s())){ Set<String> keys = returnedItem.keySet(); System.out.println("Amazon DynamoDB table attributes: \n"); for (String key1 : keys) { System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString()); } }else{ System.out.format("匹配到主键条目,但状态不为%s!\n", statusValue); } } else { // 补全格式化输出的参数 System.out.format("未找到主键为 %s + %s 的条目!\n", envNameValue, configurationNameValue); } } catch (DynamoDbException e){ e.printStackTrace(); System.exit(1); } } }
补充说明
如果你需要同时筛选status等于指定值的条目,不能直接把status放到GetItem的key里,有两种常用实现方案:
- 按照上面代码的逻辑,先通过主键查到对应条目,再在本地校验status字段的值是否符合要求,适合单条主键查询的场景。
- 如果需要批量查询满足条件的条目,可以改用
Query接口,将status配置为索引的键或者添加到FilterExpression中过滤。
内容的提问来源于stack exchange,提问作者TheWalkingMalteser
相关产品推荐
相关产品推荐

