Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS DynamoDB Python - boto3 Key() methods not recognized (Query)

I am using Lambda (Python) to query my DynamoDB database. I am using the boto3 library, and I was able to make an "equivalent" query:

This script works:

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

def create_list(event, context):
    resource = boto3.resource('dynamodb')
    table = resource.Table('Table_Name')

    response = table.query(
        TableName='Table_Name',
        IndexName='Custom-Index-Name',
        KeyConditionExpression=Key('Number_Attribute').eq(0)
    )
    return response

However, when I change the query expression to this:

KeyConditionExpression=Key('Number_Attribute').gt(0)

I get the error:

"errorType": "ClientError",
  "errorMessage": "An error occurred (ValidationException) when calling the Query operation: Query key condition not supported"

According to this [1] resource, "gt" is a method of Key(). Does anyone know if this library has been updated, or what other methods are available other than "eq"?

[1] http://boto3.readthedocs.io/en/latest/reference/customizations/dynamodb.html#ref-dynamodb-conditions

---------EDIT----------

I also just tried the old method using:

response = client.query(
        TableName = 'Table_Name',
        IndexName='Custom_Index',
        KeyConditions = {
            'Custom_Number_Attribute':{
                'ComparisonOperator':'EQ',
                'AttributeValueList': [{'N': '0'}]
            }
        }
    )

This worked, but when I try:

response = client.query(
            TableName = 'Table_Name',
            IndexName='Custom_Index',
            KeyConditions = {
                'Custom_Number_Attribute':{
                    'ComparisonOperator':'GT',
                    'AttributeValueList': [{'N': '0'}]
                }
            }
        )

...it does not work.

Why would EQ be the only method working in these cases? I'm not sure what I'm missing in the documentation.

like image 799
sean Avatar asked May 25 '16 22:05

sean


1 Answers

From what I think: Your Partition Key is Number_Attribute, and so you cannot do a gt when doing a query (you can do an eq and that is it.)

You can do a gt or between for your Sort Key when doing a query. It is also called Range key, and because it "smartly" puts the items next to each other, it offers the possibility of doing gt and between efficiently in a query

Now, if you want to do a between to your partition Key, then you will have to use scan like the below:

Key('Number_Attribute').gt(0)
response = table.scan(
    FilterExpression=fe
)

Keep in mind of the following concerning scan:

The scan method reads every item in the entire table, and returns all of the data in the table. You can provide an optional filter_expression, so that only the items matching your criteria are returned. However, note that the filter is only applied after the entire table has been scanned.

So in other words, it's a bit of a costly operation comparing to query. You can see an example in the documentation here.

Hope that helps!

like image 135
Guy Daher Avatar answered Sep 28 '22 01:09

Guy Daher