Получить все элементы из DynamoDB с помощью запроса?

Я пытаюсь получить все элементы в таблице Dynamodb с помощью запроса. Ниже мой код:

import boto.dynamodb2
from boto.dynamodb2.table import Table
from time import sleep

c    = boto.dynamodb2.connect_to_region(aws_access_key_id="XXX",aws_secret_access_key="XXX",region_name="us-west-2")

tab  = Table("rip.irc",connection=c)

x    = tab.query()

for i in x:
    print i
    sleep(1)

Однако я получаю следующую ошибку:

ValidationException: ValidationException: 400 Bad Request
{'message': 'Conditions can be of length 1 or 2 only', '__type': 'com.amazon.coral.validate#ValidationException'}

Код, который у меня есть, довольно прост и не входит в документацию boto Dynamodb2, поэтому я не уверен, почему я получаю указанную выше ошибку. Любые идеи будут оценены (новичок в этом и немного потерян). Спасибо

РЕДАКТИРОВАТЬ: у меня есть как хеш-ключ, так и ключ диапазона. Я могу запрашивать определенные хеш-ключи. Например,

x = tab.query(hash__eq="2014-01-20 05:06:29")

Как я могу получить все предметы?


person dlaser    schedule 02.02.2014    source источник


Ответы (5)


Ааа ладно, разобрался. Если кому нужно:

Вы не можете использовать метод запроса к таблице без указания конкретного хеш-ключа. Вместо этого можно использовать сканирование. Итак, если я заменю:

x    = tab.query()

с участием

x    = tab.scan()

Я получаю все предметы в своей таблице.

person dlaser    schedule 02.02.2014
comment
Это не решение, вы не собираетесь использовать сканирование для логики вашего приложения, это очень дорого! Вам следует переосмыслить свои индексы и использовать query или get_item! - person e-nouri; 09.10.2015
comment
сканирование - разумное решение для небольших таблиц. Источник: docs.aws.amazon.com/amazondynamodb/latest/developerguide/ - person Luhar; 28.06.2017
comment
.scan () также не возвращает автоматически все элементы в таблице из-за разбиения таблицы на страницы, для каждого ответа существует ограничение в 1 МБ. После этого вам нужно будет сделать последующие сканирования с атрибутом LastEvaluatedKey. - person Eph Harris; 07.05.2020

Я на заводе, но это даст вам намек. Ошибка :

{'message': 'Conditions can be of length 1 or 2 only'}

сообщает вам, что ваше ключевое условие может иметь длину 1 -> только hashKey или длину 2 -> hashKey + rangeKey. Все, что находится в запросе поверх ключей, вызовет эту ошибку. Причина этой ошибки: вы пытаетесь выполнить поисковый запрос, но используете запрос ключевое условие. Вы должны добавить отдельное filterCondition для выполнения вашего запроса. Мой код

    String keyQuery = " hashKey = :hashKey and rangeKey between :start and :end "
    queryRequest.setKeyConditionExpression(keyQuery)// define key query
    String filterExpression = " yourParam = :yourParam "
    queryRequest.setFilterExpression(filterExpression)// define filter expression
    queryRequest.setExpressionAttributeValues(expressionAttributeValues)
    queryRequest.setSelect('ALL_ATTRIBUTES')
    QueryResult queryResult = client.query(queryRequest)
person Vadim    schedule 23.08.2016
comment
Идеально! Спасибо @ Вадим, ты сэкономил мне много времени! - person Vaha; 29.08.2018

.scan () не возвращает автоматически все элементы таблицы из-за разбиения таблицы на страницы. Максимальный предел ответа составляет 1 МБ. Максимальный предел ответа Dynamodb

Вот рекурсивная реализация сканирования boto3:

import boto3
dynamo = boto3.resource('dynamodb')


def scanRecursive(tableName, **kwargs):
        """
        NOTE: Anytime you are filtering by a specific equivalency attribute such as id, name 
        or date equal to ... etc., you should consider using a query not scan

        kwargs are any parameters you want to pass to the scan operation
        """
        dbTable = dynamo.Table(tableName)
        response = dbTable.scan(**kwargs)
        if kwargs.get('Select')=="COUNT":
            return response.get('Count')
        data = response.get('Items')
        while 'LastEvaluatedKey' in response:
            response = kwargs.get('table').scan(ExclusiveStartKey=response['LastEvaluatedKey'], **kwargs)
            data.extend(response['Items'])
        return data
person Eph Harris    schedule 07.05.2020
comment
Почему бы просто не использовать предварительно созданный сканировать пагинатор? - person Sam Morgan; 25.11.2020

Я столкнулся с этой ошибкой, когда неправильно использовал KeyConditionExpression вместо FilterExpression при запросе таблицы Dynamodb.

KeyConditionExpression следует использовать только с ключом раздела или значениями ключа сортировки. FilterExpression следует использовать, если вы хотите еще больше отфильтровать результаты.

Однако обратите внимание, что при использовании FilterExpression используются те же операции чтения, что и без него, потому что он выполняет запрос на основе keyConditionExpression. Затем он удаляет элементы из результатов на основе вашего FilterExpression.

Источник Работа с запросами

person Dylan w    schedule 27.05.2019

Вот как я делаю запрос, если кому-то все еще нужно решение:

def method_name(a, b)
    results = self.query(
      key_condition_expression: '#T = :t',
      filter_expression: 'contains(#S, :s)',
      expression_attribute_names: {
        '#T' => 'your_table_field_name',
        '#S' => 'your_table_field_name'
      },
      expression_attribute_values: {
        ':t' => a,
        ':s' => b
      }
    )
    results
  end
person Adithya    schedule 12.06.2017
comment
Это бесполезный ответ на вопрос. почему вы верите, что это ответ? как это работает? Простое указание кому-то изменить свой код без какого-либо контекста или смысла не поможет им понять, что они сделали неправильно. - person GrumpyCrouton; 12.06.2017