如何在 python 中查询 AWS DynamoDB?

How do I query AWS DynamoDB in python?

我对 NoSQL 和使用 AWS DynamoDB 还很陌生。我使用 python 2.7 从 AWS Lambda 调用它 我正在尝试从 order_number 字段中检索值。
这是我的 table 的样子(只有一条记录。):

主分区键:subscription_id


和我的二级全球索引:order_number

我的设置正确吗? 如果给定 order_number 我如何使用 python 检索记录?
我不知道这样做的语法。

我试过了

response = table.get_item( Key = {'order_number': myordernumber} )

但我得到:
An error occurred (ValidationException) when calling the GetItem operation: The provided key element does not match the schema: ClientError

DynamoDB 不会自动索引对象的所有字段。默认情况下,您可以定义一个散列键(在您的情况下为 subscription_id)和一个可选的范围键,这些键将被编入索引。所以,你可以这样做:

response = table.get_item(Key={'subscription_id': mysubid})

它会按预期工作。但是,如果您想检索基于 order_number 的项目,则必须使用 scan 操作来查看 table 中的所有项目以找到正确的项目价值。这是一个非常昂贵的操作。或者您可以在 table 中创建一个使用 order_number 作为主键的全局二级索引。如果您这样做并调用了新索引 order_number-index,您就可以像这样查询与特定订单号匹配的对象:

from boto3.dynamodb.conditions import Key, Attr

response = table.query(
    IndexName='order_number-index',
    KeyConditionExpression=Key('order_number').eq(myordernumber))

DynamoDB 是一个非常快速、可扩展且高效的数据库,但它确实需要大量考虑您可能想要搜索的字段以及如何高效地进行搜索。

好消息是,现在您可以将 GSI 添加到现有 table。以前你必须删除你的 table 并重新开始。

确保你已经导入了这个:

from boto3.dynamodb.conditions import Key, Attr

如果没有,肯定会出现错误。它在 documentation examples.

感谢@altoids 上面的评论,因为这是我的正确答案。我想通过 "formal" 回答来引起注意。

要使用带过滤器的索引查询 dynamodb:

import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb', region_name=region)
table = dynamodb.Table('<TableName>')

response = table.query(
    IndexName='<Index>',
    KeyConditionExpression=Key('<key1>').eq('<value>') & Key('<key2>').eq('<value>'),
    FilterExpression=Attr('<attr>').eq('<value>')
)

print(response['Items'])

如果不需要过滤器,则不要在查询中使用 FilterExpression

import boto3
from boto3.dynamodb.conditions import Key
dynamodb = boto3.resource('dynamodb', region_name=region_name)
table = dynamodb.Table(tableName)

def queryDynamo(pk, sk):
    response = table.query(
        ProjectionExpression="#pk, #sk, keyA, keyB",
        ExpressionAttributeNames={"#pk": "pk", "#sk": "sk"},
        KeyConditionExpression=
            Key('pk').eq(pk) & Key('sk').eq(sk)
    )
    return response['Items']