2017-02-06 19 views
1

Итак, у меня есть таблица dynamodb с основным столбцом раздела раздела, foo_id и без основного ключа сортировки. У меня есть список значений foo_id, и вы хотите получить наблюдения, связанные с этим списком идентификаторов.Как batch_get_item много элементов сразу задают список значений основного ключа кластера

Я решил, что лучший способ сделать это (?) - использовать batch_get_item(), но это не работает для меня.

# python code 
    import boto3 
    client = boto3.client('dynamodb') 

    # ppk_values = list of `foo_id` values (strings) (< 100 in this example) 
    x = client.batch_get_item(
     RequestItems={ 
      'my_table_name': 
       {'Keys': [{'foo_id': {'SS': [id for id in ppk_values]}}]} 
     }) 

Я использую SS, потому что я передаю список строк (список foo_id значений), но я получаю:

ClientError: An error occurred (ValidationException) when calling the 
BatchGetItem operation: The provided key element does not match the 
schema 

Так я предполагаю, что означает, что он думает foo_id содержит вместо строковых значений, что неверно.

-> Правильно ли эта интерпретация? Каков наилучший способ пакетного запроса для группировки основных значений ключа раздела?

ответ

2

Ключи следует указывать, как указано ниже. Его нельзя назвать «SS».

В принципе, вы можете сравнить тип данных DynamoDB String со String (т. Е. Не с SS). Каждый элемент обрабатывается отдельно. Это не похож на SQL в запросе.

'Keys': [ 
        { 
         'foo_id': key1 
        }, 
        { 
         'foo_id': key2 
        }, 
       ], 

Пример кода: -

Вы, возможно, потребуется изменить имя таблицы и ключевые ценности.

from __future__ import print_function # Python 2/3 compatibility 
import boto3 
import json 
import decimal 
from boto3.dynamodb.conditions import Key, Attr 
from botocore.exceptions import ClientError 

# Helper class to convert a DynamoDB item to JSON. 
class DecimalEncoder(json.JSONEncoder): 
    def default(self, o): 
     if isinstance(o, decimal.Decimal): 
      if o % 1 > 0: 
       return float(o) 
      else: 
       return int(o) 
     return super(DecimalEncoder, self).default(o) 

dynamodb = boto3.resource("dynamodb", region_name='us-west-2', endpoint_url="http://localhost:8000") 

email1 = "[email protected]" 
email2 = "[email protected]" 

try: 
    response = dynamodb.batch_get_item(
    RequestItems={ 
     'users': { 
      'Keys': [ 
       { 
        'email': email1 
       }, 
       { 
        'email': email2 
       }, 
      ],    
      'ConsistentRead': True    
     } 
    }, 
    ReturnConsumedCapacity='TOTAL' 
) 
except ClientError as e: 
    print(e.response['Error']['Message']) 
else: 
    item = response['Responses'] 
    print("BatchGetItem succeeded:") 
    print(json.dumps(item, indent=4, cls=DecimalEncoder)) 
+0

выше ответ работает только после того, как мы изменяем dynamodb.batch_get_item к dynamodb.meta.client.batch_get_item, как метод batch_get_item существует только на клиенте не на ресурсе. –