Есть ли способ эффективно извлекать все результаты из DynamoDB среднего размера?

#amazon-web-services #aws-lambda #amazon-dynamodb #boto3 #dynamodb-queries

#amazon-web-services #aws-lambda #amazon-dynamodb #boto3 #dynamodb-запросы

Вопрос:

Я использую boto3 с python, но я считаю, что проблема и логика должны быть универсальными для всех языков.

Я знаю, что table.scan() теоретически это должно возвращать все записи, но на самом деле результаты сканирования () ограничены размером 1 МБ. Рекомендуется создавать цикл while на основе LastEvaluatedKey , но это также не дает мне всех результатов (15200 вместо 16000), код здесь:

 dynamodb = boto3.resource('dynamodb', region_name='eu-west-2')
table = dynamodb.Table(dBTable)
response = table.scan()
print("item_count:", table.item_count)
print("response1:", response["Count"])

items=[]
while 'LastEvaluatedKey' in response and response['LastEvaluatedKey'] != "":  
    print("response:", response["Count"])
    items =response["Items"]
    response = table.scan(ExclusiveStartKey=response['LastEvaluatedKey'])
  

Как я могу надежно извлекать все записи?

Ответ №1:

Рекомендуется создать цикл while на основе LastEvaluatedKey, но это также не дает мне всех результатов (15200 вместо 16000).

Вы уверены в этом? Я предполагаю, что у вас происходит что-то еще. Я использую boto3 и LastEvaludatedKey в цикле производственного кода, который выполняется каждый день, и никогда не сталкивался со случаем, когда возвращались не все строки — не говорю, что это невозможно, но сначала я бы убедился, что ваш код правильный.

Редактировать, этот код работает:

 import boto3

from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('DeadLetterQueue')
response = table.scan()
print("item_count:", table.item_count)

items=response["Items"]
while 'LastEvaluatedKey' in response and response['LastEvaluatedKey'] != "":  
    response = table.scan(ExclusiveStartKey=response['LastEvaluatedKey'])
    items.extend(response["Items"])


print (len(items))
  

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

1. Я добавил код к своему вопросу, не могли бы вы взглянуть? Я запускаю это на lambda — если это имеет значение

2. Я добавил для вас рабочий код, немного отличающийся от вашего, но вы должны быть в состоянии его адаптировать.

3. спасибо, это сработало! все дело было в порядке строк

Ответ №2:

Проблема, с которой вы столкнулись, не связана с операцией сканирования DynamoDB. Это связано с вашим кодом. Последняя операция сканирования не добавляется к массиву элементов.

Ниже приведен ваш код с небольшими изменениями —

 dynamodb = boto3.resource('dynamodb', region_name='eu-west-2')
table = dynamodb.Table(dBTable)
response = table.scan()
print("item_count:", table.item_count)
print("response1:", response["Count"])

items=response["Items"] // Changed HERE.
while 'LastEvaluatedKey' in response and response['LastEvaluatedKey'] != "":  
    response = table.scan(ExclusiveStartKey=response['LastEvaluatedKey'])
    print("response:", response["Count"])
    items =response["Items"] // Shifted this line HERE