13

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.

1

1 Answer 1

14

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!

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry for the delay, I actually got this same answer from AWS Support. You're exactly right, eq is required on the Primary Key. The way I solve this issue is to always add an attribute to each table that holds the same value for all entries that I want to query. That way I can conduct the Query, and also have the option of removing items from accessibility (changing the value of that general attribute) for a general Query. This way it's similar to a Scan, but gives a few more options.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.