我如何从 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 以仅包含关键属性(envNameconfigurationName),并确保它们具有正确的数据类型(均为字符串)。

要验证发生了什么,使用 awscli 来确认您的假设通常很有用。下面是一个示例,说明如何使用 awscli 发出相同的 GetItem 调用:

aws dynamodb get-item \
    --table-name mytable \
    --key '{"envName":{"S":"env1"}, "configurationName":{"S":"config1"}}'

有关 DynamoDB 的一些重要背景知识:如果不指明其完整密钥,您将无法获取项目,在您的情况下是 envNameconfigurationName。如果您实际上想要具有给定 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,);