使用查询从 DynamoDB 检索所有项目?

问题描述 投票:0回答:6

我正在尝试使用查询检索 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")

我怎样才能取回所有物品?

python boto amazon-dynamodb
6个回答
64
投票

啊好吧,明白了。如果有人需要:

如果不指定特定的哈希键,则无法对表使用查询方法。可以使用的方法是扫描。所以如果我更换:

x    = tab.query()

x    = tab.scan()

我得到了我桌子上的所有物品。


13
投票

我很喜欢,但它会给你一个提示。错误:

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

告诉你,你的关键条件可以是长度1 -> hashKey only,或者长度2 -> hashKey + rangeKey。键顶部查询中的所有内容都会引发此错误。 此错误的原因是:您尝试运行 search 查询,但使用 key condition 查询。您必须添加单独的 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)

13
投票
由于表格分页,

.scan() 不会自动返回表格的所有元素。有 1Mb 最大响应限制 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

3
投票

当我在查询 dynamodb 表时误用

KeyConditionExpression
而不是
FilterExpression
时,我遇到了这个错误。

KeyConditionExpression
只能与分区键或排序键值一起使用。 当您想要进一步过滤结果时,应使用
FilterExpression

但是请注意,使用

FilterExpression
所使用的读取与不使用时相同,因为它基于
keyConditionExpression
执行查询。然后,它会根据您的
FilterExpression
从结果中删除项目。

来源 使用查询


0
投票

受到其他答案和评论的启发。如果需要所有记录,请使用

scan
而不是
query
(它需要关键过滤器)。

参考:扫描分页器('扫描')

import boto3
from boto3.dynamodb.types import TypeDeserializer

session = boto3.Session()
client = session.client("dynamodb")

paginator = client.get_paginator('scan')

response_iterator = paginator.paginate(
    TableName=table_name
)

data = []
for page in response_iterator:
    for item in page['Items']:
        # convert to python types
        deserializer = TypeDeserializer()
        python_data = {k: deserializer.deserialize(v) for k, v in item.items()}

        # append to list
        data.append(python_data['data'])

-5
投票

如果有人仍然需要解决方案,这就是我进行查询的方式:

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
© www.soinside.com 2019 - 2024. All rights reserved.