如何在python中查询AWS DynamoDB?

时间:2015-12-09 05:45:57

标签: python amazon-web-services aws-lambda nosql

我是NoSQL并且使用AWS DynamoDB的新手。我是使用python 2.7从AWS Lambda调用的 我正在尝试从'order_number'字段中检索值 这就是我的桌子看起来的样子(只有一条记录。):
enter image description here

主分区键:subscription_id enter image description here


和我的二级全局索引:order_number
enter image description here

我的设置是否正确? 如果是这样,给定order_number如何使用python检索记录?
我无法弄清楚这样做的语法。

我试过了

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

但我明白了:
调用GetItem操作时发生错误(ValidationException):提供的键元素与架构不匹配:ClientError

4 个答案:

答案 0 :(得分:12)

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

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

它将按预期工作。但是,如果要根据order_number检索项目,则必须使用scan操作查看表中的所有项目以查找具有正确值的项目。这是一项非常昂贵的操作。或者,您可以在表中创建使用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添加到现有表中。以前你必须删除你的表并重新开始。

答案 1 :(得分:7)

确保您已导入此内容:

from boto3.dynamodb.conditions import Key, Attr

如果你没有,你肯定会得到错误。它位于documentation examples

感谢@altoids上面的评论,因为这是我的正确答案。我希望通过“正式”答案引起注意。

答案 2 :(得分:2)

要使用带有过滤器的索引来查询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

答案 3 :(得分:0)

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']