我如何从 dynamodb table 获取项目?
How do i get an item from dynamodb table?
我正在尝试使用以下代码检查我的 dynamodb table 中是否存在某个项目:
一旦我可以取回物品,我希望能够 运行 一些东西。分区键是 envName,排序键是 configurationName
package com.dev.newlibs;
//all relevant imports added here
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();
client.close();
updateEnvDashboard(client, tableName, configurationName, configurationNameValue, envName, envNameValue, status, statusValue,);
}
public static void updateEnvDashboard(DynamoDbClient client,
String tableName,
String configurationName,
String configurationNameValue,
String envName,
String envNameValue,
String status,
String statusValue,) throws Exception {
//Get item to see if it exists
HashMap<String,AttributeValue> itemToGet = new HashMap<String,AttributeValue>();
itemToGet.put(configurationName, AttributeValue.builder().s(configurationNameValue).build());
itemToGet.put(status, AttributeValue.builder().s(statusValue).build());
itemToGet.put(envName, AttributeValue.builder().s(envNameValue).build());
GetItemRequest request = GetItemRequest.builder()
.key(itemToGet)
.tableName(tableName)
.build();
//run a get request and see what is returned. do something depending on what is returned
try {
Map<String,AttributeValue> returnedItem = client.getItem(request).item();
if (returnedItem != null) {
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("No item found with the key %s!\n");
}
} catch (DynamoDbException e){
e.printStackTrace();
System.exit(1);
}
}
}
当运行宁此我得到错误:
software.amazon.awssdk.services.dynamodb.model.DynamoDbException: The provided key element does not match the schema
我在这里错过了什么?我尝试按照官方 aws repo
中的 getItem 示例
调用 GetItem.
时,您必须提供具有正确类型的关键属性
您包含了非关键属性 (status
)。当您提供非键属性时,您的 GetItem 请求将失败并出现 ValidationException,包括此错误消息:
The provided key element does not match the schema
修改您的 GetItemRequest 以仅包含关键属性(envName
和 configurationName
),并确保它们具有正确的数据类型(均为字符串)。
要验证发生了什么,使用 awscli 来确认您的假设通常很有用。下面是一个示例,说明如何使用 awscli 发出相同的 GetItem 调用:
aws dynamodb get-item \
--table-name mytable \
--key '{"envName":{"S":"env1"}, "configurationName":{"S":"config1"}}'
有关 DynamoDB 的一些重要背景知识:如果不指明其完整密钥,您将无法获取项目,在您的情况下是 envName
加 configurationName
。如果您实际上想要具有给定 envName
的所有项目而不是特定的单个项目,那么您可以仅使用 envName
分区键发出查询(而不是 GetItem)。您不能 get/query 排序键,因此您将无法查询具有给定 configurationName
的所有项目...除非您在该排序键属性上创建全局二级索引 (GSI),然后指明查询时的 GSI 名称。
我建议您查看使用 Amazon DynamoDB 增强客户端获取项目。使用增强的客户端,您可以将客户端 class 映射到 DynamoDB table。有关详细信息,请参阅 Using the DynamoDB Enhanced Client in the AWS SDK for Java 2.x.
例如,假设您想从客户table获取客户数据。
这里是 客户 Java class.
package com.example.dynamodb;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
import software.amazon.awssdk.enhanced.dynamodb.model.BatchWriteItemEnhancedRequest;
import software.amazon.awssdk.enhanced.dynamodb.model.WriteBatch;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
/**
* This class is used by the Enhanced Client examples.
*/
@DynamoDbBean
public class Customer {
private String id;
private String name;
private String email;
private Instant regDate;
@DynamoDbPartitionKey
public String getId() {
return this.id;
};
public void setId(String id) {
this.id = id;
}
public String getCustName() {
return this.name;
}
public void setCustName(String name) {
this.name = name;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public Instant getRegistrationDate() {
return regDate;
}
public void setRegistrationDate(Instant registrationDate) {
this.regDate = registrationDate;
}
}
您可以使用此代码获取客户记录:
package com.example.dynamodb;
// snippet-start:[dynamodb.java2.mapping.getitem.import]
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import java.time.Instant;
// snippet-end:[dynamodb.java2.mapping.getitem.import]
/*
* Prior to running this code example, create an Amazon DynamoDB table named Customer with these columns:
* - id - the id of the record that is the key
* - custName - the customer name
* - email - the email value
* - registrationDate - an instant value when the item was added to the table
*
* Also, ensure that you have setup your development environment, including your credentials.
*
* For information, see this documentation topic:
*
* https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
*/
public class EnhancedGetItem {
public static void main(String[] args) {
Region region = Region.US_EAST_1;
DynamoDbClient ddb = DynamoDbClient.builder()
.region(region)
.build();
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(ddb)
.build();
String result = getItem(enhancedClient);
System.out.println(result);
ddb.close();
}
// snippet-start:[dynamodb.java2.mapping.getitem.main]
public static String getItem(DynamoDbEnhancedClient enhancedClient) {
try {
//Create a DynamoDbTable object
DynamoDbTable<Customer> mappedTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
//Create a KEY object
Key key = Key.builder()
.partitionValue("id146")
.build();
// Get the item by using the key
Customer result = mappedTable.getItem(r->r.key(key));
return "The email value is "+result.getEmail();
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
// snippet-end:[dynamodb.java2.mapping.getitem.main]
}
如您在此调试视图中所见,此代码检索客户记录。
此外 - 在您线程的代码示例中,您在调用方法之前关闭了客户端:
DynamoDbClient client = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.build();
client.close(); // bug here
updateEnvDashboard(client, tableName, configurationName, configurationNameValue, envName, envNameValue, status, statusValue,);
我正在尝试使用以下代码检查我的 dynamodb table 中是否存在某个项目: 一旦我可以取回物品,我希望能够 运行 一些东西。分区键是 envName,排序键是 configurationName
package com.dev.newlibs;
//all relevant imports added here
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();
client.close();
updateEnvDashboard(client, tableName, configurationName, configurationNameValue, envName, envNameValue, status, statusValue,);
}
public static void updateEnvDashboard(DynamoDbClient client,
String tableName,
String configurationName,
String configurationNameValue,
String envName,
String envNameValue,
String status,
String statusValue,) throws Exception {
//Get item to see if it exists
HashMap<String,AttributeValue> itemToGet = new HashMap<String,AttributeValue>();
itemToGet.put(configurationName, AttributeValue.builder().s(configurationNameValue).build());
itemToGet.put(status, AttributeValue.builder().s(statusValue).build());
itemToGet.put(envName, AttributeValue.builder().s(envNameValue).build());
GetItemRequest request = GetItemRequest.builder()
.key(itemToGet)
.tableName(tableName)
.build();
//run a get request and see what is returned. do something depending on what is returned
try {
Map<String,AttributeValue> returnedItem = client.getItem(request).item();
if (returnedItem != null) {
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("No item found with the key %s!\n");
}
} catch (DynamoDbException e){
e.printStackTrace();
System.exit(1);
}
}
}
当运行宁此我得到错误:
software.amazon.awssdk.services.dynamodb.model.DynamoDbException: The provided key element does not match the schema
我在这里错过了什么?我尝试按照官方 aws repo
中的 getItem 示例调用 GetItem.
时,您必须提供具有正确类型的关键属性您包含了非关键属性 (status
)。当您提供非键属性时,您的 GetItem 请求将失败并出现 ValidationException,包括此错误消息:
The provided key element does not match the schema
修改您的 GetItemRequest 以仅包含关键属性(envName
和 configurationName
),并确保它们具有正确的数据类型(均为字符串)。
要验证发生了什么,使用 awscli 来确认您的假设通常很有用。下面是一个示例,说明如何使用 awscli 发出相同的 GetItem 调用:
aws dynamodb get-item \
--table-name mytable \
--key '{"envName":{"S":"env1"}, "configurationName":{"S":"config1"}}'
有关 DynamoDB 的一些重要背景知识:如果不指明其完整密钥,您将无法获取项目,在您的情况下是 envName
加 configurationName
。如果您实际上想要具有给定 envName
的所有项目而不是特定的单个项目,那么您可以仅使用 envName
分区键发出查询(而不是 GetItem)。您不能 get/query 排序键,因此您将无法查询具有给定 configurationName
的所有项目...除非您在该排序键属性上创建全局二级索引 (GSI),然后指明查询时的 GSI 名称。
我建议您查看使用 Amazon DynamoDB 增强客户端获取项目。使用增强的客户端,您可以将客户端 class 映射到 DynamoDB table。有关详细信息,请参阅 Using the DynamoDB Enhanced Client in the AWS SDK for Java 2.x.
例如,假设您想从客户table获取客户数据。
这里是 客户 Java class.
package com.example.dynamodb;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
import software.amazon.awssdk.enhanced.dynamodb.model.BatchWriteItemEnhancedRequest;
import software.amazon.awssdk.enhanced.dynamodb.model.WriteBatch;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
/**
* This class is used by the Enhanced Client examples.
*/
@DynamoDbBean
public class Customer {
private String id;
private String name;
private String email;
private Instant regDate;
@DynamoDbPartitionKey
public String getId() {
return this.id;
};
public void setId(String id) {
this.id = id;
}
public String getCustName() {
return this.name;
}
public void setCustName(String name) {
this.name = name;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public Instant getRegistrationDate() {
return regDate;
}
public void setRegistrationDate(Instant registrationDate) {
this.regDate = registrationDate;
}
}
您可以使用此代码获取客户记录:
package com.example.dynamodb;
// snippet-start:[dynamodb.java2.mapping.getitem.import]
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import java.time.Instant;
// snippet-end:[dynamodb.java2.mapping.getitem.import]
/*
* Prior to running this code example, create an Amazon DynamoDB table named Customer with these columns:
* - id - the id of the record that is the key
* - custName - the customer name
* - email - the email value
* - registrationDate - an instant value when the item was added to the table
*
* Also, ensure that you have setup your development environment, including your credentials.
*
* For information, see this documentation topic:
*
* https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
*/
public class EnhancedGetItem {
public static void main(String[] args) {
Region region = Region.US_EAST_1;
DynamoDbClient ddb = DynamoDbClient.builder()
.region(region)
.build();
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(ddb)
.build();
String result = getItem(enhancedClient);
System.out.println(result);
ddb.close();
}
// snippet-start:[dynamodb.java2.mapping.getitem.main]
public static String getItem(DynamoDbEnhancedClient enhancedClient) {
try {
//Create a DynamoDbTable object
DynamoDbTable<Customer> mappedTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
//Create a KEY object
Key key = Key.builder()
.partitionValue("id146")
.build();
// Get the item by using the key
Customer result = mappedTable.getItem(r->r.key(key));
return "The email value is "+result.getEmail();
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
// snippet-end:[dynamodb.java2.mapping.getitem.main]
}
如您在此调试视图中所见,此代码检索客户记录。
此外 - 在您线程的代码示例中,您在调用方法之前关闭了客户端:
DynamoDbClient client = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.build();
client.close(); // bug here
updateEnvDashboard(client, tableName, configurationName, configurationNameValue, envName, envNameValue, status, statusValue,);