Java: не удается удалить значение элемента dynamodb

#java #amazon-web-services #amazon-dynamodb

Вопрос:

Я пытаюсь удалить поле под названием «собака» из всех элементов, которые находятся в таблице животные, или что я использую следующий код:

     Table table= dynamoDB.getTable("animals");
    ScanRequest scanRequest = new ScanRequest().withTableName("animals");
    ScanResult result = client.scan(scanRequest);


    for (Map<String, AttributeValue> item : result.getItems()){

        table.updateItem(new PrimaryKey("<Primary partition key name>", item.get("<Primary partition key name>"),"<Primary sort key name>", item.get("<Primary sort key name>")), 
new AttributeUpdate("dog").delete());

    }
 

Но я получаю:

     Exception in thread "main" java.lang.RuntimeException: value type: class com.amazonaws.services.dynamodbv2.model.AttributeValue
.
.
.
    Caused by: java.lang.UnsupportedOperationException: value type: class com.amazonaws.services.dynamodbv2.model.AttributeValue
 

Что я здесь делаю не так?

кстати, я тоже пытался:

    UpdateItemSpec updateItemSpec = new UpdateItemSpec()
                    .withPrimaryKey("<Primary partition key name>", item.get("<Primary partition key name>"),"<Primary sort key name>", item.get("<Primary sort key name>"))
                    .withUpdateExpression("REMOVE dog");
            table.updateItem(updateItemSpec);
 

Но получил такое же исключение. (Также попытался УДАЛИТЬ вместо УДАЛЕНИЯ)

Ответ №1:

Вы используете старый API DynamoDB V1, что не является лучшей практикой. Лучше использовать Java-API Amazon DynamoDB V2.

Пакет SDK AWS для Java 2.x представляет собой крупную переработку базы кода версии 1.x. Он построен поверх Java 8 и добавляет несколько часто запрашиваемых функций. Они включают поддержку неблокирующего ввода-вывода и возможность подключения другой реализации HTTP во время выполнения.

Если вы не знакомы с AWS SDK для Java V2, см.:

Начните работу с AWS SDK для Java 2.x

Для этого варианта использования (который заключается в изменении элемента) решением является использование расширенного клиента, который позволяет сопоставлять объекты Java с таблицей. Для получения дополнительной информации см.:

Сопоставление элементов в таблицах таблицах DynamoDB

Используя расширенный Клинт, вы можете изменить элемент с помощью кода, подобного этому:

     package com.example.dynamodb;


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;


/*
 * 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 EnhancedModifyItem {

    public static void main(String[] args) {


        String usage = "Usage:n"  
                "    UpdateItem <key> <email> nn"  
                "Where:n"  
                "    key - the name of the key in the table (id120).n"  
                "    email - the value of the modified email column.n" ;

       if (args.length != 2) {
            System.out.println(usage);
            System.exit(1);
       }

        String key = args[0];
        String email = args[1];
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();

        String updatedValue = modifyItem(enhancedClient,key,email);
        System.out.println("The updated name value is " updatedValue);
        ddb.close();
    }


    public static String modifyItem(DynamoDbEnhancedClient enhancedClient, String keyVal, String email) {
        try {
            //Create a DynamoDbTable object
            DynamoDbTable<Customer> mappedTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));

            //Create a KEY object
            Key key = Key.builder()
                    .partitionValue(keyVal)
                    .build();

            // Get the item by using the key and update the email value.
            Customer customerRec = mappedTable.getItem(r->r.key(key));
            customerRec.setEmail(email);
            mappedTable.updateItem(customerRec);
            return customerRec.getEmail();

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        return "";
    }
}
 

Вы можете найти этот пример версии 2 и другие для Amazon DynamoDB здесь:

https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/javav2/example_code/dynamodb

Комментарии:

1. Привет, спасибо за ваш ответ! На самом деле я использую dynamodbv2, т. Е.: «com.amazonaws.services.dynamodbv2.AmazonDynamoDB». Обратите внимание, что мой вопрос заключается в том, как удалить значение внутри элемента, но не сам элемент.

2. dynamodbv2 по-прежнему является V1. Обратите внимание, что любой пакет, начинающийся с com.amazonaws.services… пакеты is v1. V2 являются программным обеспечением.amazon.awssdk.services.dynamodb…

3. О, я скучал по этому! Спасибо. Теперь мне просто нужно выяснить, как удалить значение свойства внутри элемента.

4. Вы пытались обновить этот элемент без определенного значения столбца?

5. Смотрите этот код — использование расширенного клиента для API DynamoDB для изменения элемента.

Ответ №2:

Я нашел решение этой проблемы, не могу поверить, что пропустил его…. Помните, дети, при отладке обязательно смотреть на фактические значения!

Поэтому вместо того, чтобы использовать только:

 item.get("<property name>")
 

Вам нужно явно запросить строку, например:

 item.get("<property name>").getS()