boto dynamodb2: Can I query a table using range key only?

蓝咒 提交于 2019-12-30 04:41:44

问题


In one of my python application, I am using boto and I want to query a dynamodb table using range key only. I don't want to use scan.

Schema for ratings table

ratings = Table.create('ratings', schema=[
    HashKey('user_id', data_type=NUMBER),
    RangeKey('photo_id', data_type=NUMBER)
], throughput={
    'read': 5,
    'write': 15,
}, indexes = [
    AllIndex('rating_allindex', parts=[
        HashKey('user_id', data_type=NUMBER),
        RangeKey('photo_id', data_type=NUMBER)
    ])
])


from boto.dynamodb2.table import Table
ratings = Table('ratings')
# photo_id is range_key and user_id is hash_key
ratings_list = ratings.query(photo_id__eq=1)

On doing so, I get this error Query condition missed key schema element user_id. Again, I thought I could give a filter condition to my hash_key

ratings_list = ratings.query(user_id__gte=1, photo_id__eq=1)

But it showed the error, Query key condition not supported. I suppose only the filter __eq is allowed with hash_key. How do I achieve what I want?


回答1:


When using a Query operation on DynamoDB you must supply one hash key, it is not defined as part of the range_key_conditions as you can see in the documentation - so you will have to use user_id_eq as you already figured out.

If you need to get rows from more than one hash key in one API call, you must use Scan (you can fetch multiple rows using batchGet but this is irrelevant to your scenario)

P.s, it appears your secondary index is the same as the Range key, is that a mistake?




回答2:


The behavior you want can be achieved using a global secondary index that uses photo_id as a hash key.




回答3:


In AWS SDKv2 you can scan table using AWSDynamoDBScanExpression, eg. iOS:

 AWSDynamoDBObjectMapper *dynamoDBObjectMapper = [AWSDynamoDBObjectMapper defaultDynamoDBObjectMapper];
 AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new];
 scanExpression.exclusiveStartKey = nil;
 scanExpression.limit = @20;
 [[[dynamoDBObjectMapper scan:[DDBTableRow class]
                   expression:scanExpression]
   continueWithExecutor:[BFExecutor mainThreadExecutor] withSuccessBlock:^id(BFTask *task) {...}

If you need a condition can use AWSDynamoDBCondition:

 AWSDynamoDBCondition *condition = [AWSDynamoDBCondition new];
 AWSDynamoDBAttributeValue *attribute = [AWSDynamoDBAttributeValue new];
 attribute.N = @"400";
 condition.attributeValueList = @[attribute];
 condition.comparisonOperator = AWSDynamoDBComparisonOperatorEQ;
 scanExpression.scanFilter = @{@"latitude": condition};


来源:https://stackoverflow.com/questions/20450479/boto-dynamodb2-can-i-query-a-table-using-range-key-only

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!