1
votes

This is how my table looks like:

enter image description here

toHash is my primary partition key and timestamp is the sort key.

So, when I am executing this code [For getting the reverse sorted list of timestamp]:

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

client = boto3.client('dynamodb')
response = client.query(
    TableName='logs',
    Limit=1,
    ScanIndexForward=False,
    KeyConditionExpression="toHash = :X",
)

I get the following error:

botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the Query operation: Invalid KeyConditionExpression: An expression attribute value used in expression is not defined; attribute value: :X

Am I doing something wrong here? Why isn't X considered a valid attribute value?

2
You need to provide an ExpressionAttributeValues clause to the query to supply the value for :X in the query.garnaat

2 Answers

4
votes

This is why I don't use boto directly anymore. The API for what should be simple stuff like this is nuts. @notionquest is correct, you need to add the ExpressionAttributeValues. I don't mess with these things anymore. I use dynamof. Heres an example with your query:

from boto3 import client
from dynamof import db as make_db
from dynamof import query

client = client('dynamodb', endpoint_url='http://localstack:4569')
db = make_db(client)

db(query(
    table_name='logs',
    conditions=attr('toHash').equals('somevalue')
))

dynamof build the KeyConditionExpression and ExpressionAttributeValues for you.

disclaimer: I wrote dynamof

2
votes

Add ExpressionAttributeValues as mentioned below:-

response = client.query(
    TableName='logs',
    Limit=1,
    ScanIndexForward=False,
    KeyConditionExpression="toHash = :X",
    ExpressionAttributeValues={":X" : {"S" : "somevalue"}}
)