mboudreau / Alternator

A mock DynamoDB that runs locally for testing purposes - DEPRECATED, PLEASE USE DYNAMODB LOCAL: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html
Apache License 2.0
78 stars 39 forks source link

BatchGetItem Returns Keys as well as Values #41

Open DanielMendeley opened 12 years ago

DanielMendeley commented 12 years ago

I'm seeing inconsistent results between DynamoDB and AlternatorDB: when doing a BatchGetItems, DynamoDB doesn't return the key as one of the Item AttributeValues, but AlternatorDB does.

Repro steps: Create table:

dynamoDbClient.createTable(
    new CreateTableRequest().withTableName("test1").withKeySchema(new KeySchema(new KeySchemaElement().withAttributeName("id").withAttributeType("S"))).withProvisionedThroughput(new ProvisionedThroughput().withReadCapacityUnits(10L).withWriteCapacityUnits(10L)));

Add rows:

 Map<String, AttributeValue> content = new HashMap<String, AttributeValue>();
content.put("id", new AttributeValue().withS("100"));
content.put("recommendations", new AttributeValue().withSS("orange", "lemon", "common"));
 dynamoDbClient.putItem(new PutItemRequest("test1", content));

content = new HashMap<String, AttributeValue>();
content.put("id", new AttributeValue().withS("100"));
content.put("recommendations", new AttributeValue().withSS("orange", "lemon", "common"));
dynamoDbClient.putItem(new PutItemRequest("test1", content));

Prepare batch request

List<Key> keys = new ArrayList<Key>();
keys.add(new Key().withHashKeyElement(new AttributeValue("100")));
keys.add(new Key().withHashKeyElement(new AttributeValue("101")));

KeysAndAttributes keysAndAttributes = new KeysAndAttributes().withKeys(keys).withAttributesToGet("recommendations");

Map<String, KeysAndAttributes> stuffToGet = new HashMap<String, KeysAndAttributes>();
stuffToGet.put(getTableName(), keysAndAttributes);

BatchGetItemRequest get = new BatchGetItemRequest().withRequestItems(stuffToGet);

Get item, process

BatchGetItemResult result = dynamoClient.batchGetItem(get);
List<String> recommendations = new ArrayList<String>();

        for (BatchResponse response : result.getResponses().values()) {
            for (Map<String, AttributeValue> row : response.getItems()) {
                for (AttributeValue value : row.values()) {
                    recommendations.addAll(value.getSS()); //NPE thrown here as "id" turns up as a value, and correctly returns null for getSS()
                }
            }
        }
        return recommendations;

I've verified this by swapping between implementations (DynamoDB and AlternatorDB).

Loving the project, keep up the good work!