The main thing to remember is that a batch_get call on a table with a hash key and a range (or sort) key requires both keys for the request. If you have a list of hash keys and the range key is constant, you can use map with a lambda to combine them into a list of tuples:
list_of_tuples = list(map(lambda x: (x, "constant-range-key"), hash_key_listlike
PynamoDB and batch_get without a Range Key#
PynamoDB requires a list of dicts when calling batch_get on a model with a hash and range key. If you try calling it with a set or list (which is allowed because not all models will include a range key), then the string hash keys will be interpreted as a tuple of strings, with the first character being interpreted as the hash key and the second one interpreted as a range key.
This could result in head-scratching errors like a duplicate-item error when a set is passed in. This can also happen with BatchWriteItem operations.
Exceptions#
pynamodb.exceptions.PutError: Failed to batch write items: An error occurred (ValidationException) on request ($id) on table ($table) when calling the BatchWriteItem operation: Provided list of item keys contains duplicates
Pynamo Code for Get#
if range_key_attribute:
hash_key, range_key = cls._serialize_keys(item[0], item[1]) # type: ignore
keys_to_get.append({
hash_key_attribute.attr_name: hash_key,
range_key_attribute.attr_name: range_key
})
else:
hash_key = cls._serialize_keys(item)[0]
keys_to_get.append({
hash_key_attribute.attr_name: hash_key
})
Sources#
- Using Python Lambdas to construct combination keys
- Attempting to use is_in to preserve batch_get and failing
- Why a tuple must always be passed to batch_get on a Pynamo model with hash and range keys