Repository: getmoto/moto

Issue:
DynamoDB - BatchGetItem should throw an error when requesting more than 100 items
Docs: 
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.batch_get_item

> If you request more than 100 items, BatchGetItem returns a ValidationException with the message "Too many items requested for the BatchGetItem call."

The docs fail to mention that there are two different use cases: request more than 100 keys for a single table, or request more than a 100 keys across all tables. DDB throws different error messages for both scenarios.

PR that handles both cases incoming shortly.



Discussion:

Resolving patch:
diff --git a/moto/dynamodb2/responses.py b/moto/dynamodb2/responses.py
--- a/moto/dynamodb2/responses.py
+++ b/moto/dynamodb2/responses.py
@@ -371,6 +371,26 @@ def batch_get_item(self):
 
         results = {"ConsumedCapacity": [], "Responses": {}, "UnprocessedKeys": {}}
 
+        # Validation: Can only request up to 100 items at the same time
+        # Scenario 1: We're requesting more than a 100 keys from a single table
+        for table_name, table_request in table_batches.items():
+            if len(table_request["Keys"]) > 100:
+                return self.error(
+                    "com.amazonaws.dynamodb.v20111205#ValidationException",
+                    "1 validation error detected: Value at 'requestItems."
+                    + table_name
+                    + ".member.keys' failed to satisfy constraint: Member must have length less than or equal to 100",
+                )
+        # Scenario 2: We're requesting more than a 100 keys across all tables
+        nr_of_keys_across_all_tables = sum(
+            [len(req["Keys"]) for _, req in table_batches.items()]
+        )
+        if nr_of_keys_across_all_tables > 100:
+            return self.error(
+                "com.amazonaws.dynamodb.v20111205#ValidationException",
+                "Too many items requested for the BatchGetItem call",
+            )
+
         for table_name, table_request in table_batches.items():
             keys = table_request["Keys"]
             if self._contains_duplicates(keys):


Test patch:
diff --git a/tests/test_dynamodb2/test_dynamodb.py b/tests/test_dynamodb2/test_dynamodb.py
--- a/tests/test_dynamodb2/test_dynamodb.py
+++ b/tests/test_dynamodb2/test_dynamodb.py
@@ -3038,6 +3038,54 @@ def test_batch_items_returns_all():
     ]
 
 
+@mock_dynamodb2
+def test_batch_items_throws_exception_when_requesting_100_items_for_single_table():
+    dynamodb = _create_user_table()
+    with assert_raises(ClientError) as ex:
+        dynamodb.batch_get_item(
+            RequestItems={
+                "users": {
+                    "Keys": [
+                        {"username": {"S": "user" + str(i)}} for i in range(0, 104)
+                    ],
+                    "ConsistentRead": True,
+                }
+            }
+        )
+    ex.exception.response["Error"]["Code"].should.equal("ValidationException")
+    msg = ex.exception.response["Error"]["Message"]
+    msg.should.contain("1 validation error detected: Value")
+    msg.should.contain(
+        "at 'requestItems.users.member.keys' failed to satisfy constraint: Member must have length less than or equal to 100"
+    )
+
+
+@mock_dynamodb2
+def test_batch_items_throws_exception_when_requesting_100_items_across_all_tables():
+    dynamodb = _create_user_table()
+    with assert_raises(ClientError) as ex:
+        dynamodb.batch_get_item(
+            RequestItems={
+                "users": {
+                    "Keys": [
+                        {"username": {"S": "user" + str(i)}} for i in range(0, 75)
+                    ],
+                    "ConsistentRead": True,
+                },
+                "users2": {
+                    "Keys": [
+                        {"username": {"S": "user" + str(i)}} for i in range(0, 75)
+                    ],
+                    "ConsistentRead": True,
+                },
+            }
+        )
+    ex.exception.response["Error"]["Code"].should.equal("ValidationException")
+    ex.exception.response["Error"]["Message"].should.equal(
+        "Too many items requested for the BatchGetItem call"
+    )
+
+
 @mock_dynamodb2
 def test_batch_items_with_basic_projection_expression():
     dynamodb = _create_user_table()