Search code examples
pythonboto3dynamodb-queries

boto3 KeyConditionExpression on both partition and sort key


So i have the following schema:

domain (partition key)

time_stamp (sort key)

I am (attempting) to use boto to query dynamo. I want to return all records with a given domain, after a given time_stamp.

I have tried a couple of different approaches to no avail:

First is my ideal approach. I believe it to be much cleaner it also uses between which i would like to incorporate if possible.

resp = table.query(
            KeyConditionExpression=Key('domain').eq(domain) and Key('time_stamp').between(start,end),
            ProjectionExpression= 'time_stamp,event_type,country,tablet,mobile,desktop')


ERROR: An error occurred (ValidationException) when calling the Query operation: 
Query condition missed key schema element: domain

Here is the second approach that I took. It appeared more often in docs and other stack questions that I found. Yet, I am still getting an error.

resp = table.query(
            ExpressionAttributeNames={
            '#nd': 'domain',
            '#nts': 'time_stamp'
            },
            ExpressionAttributeValues={
            ':vd': domain,
            ':vts': start,
            },
            KeyConditionExpression='(#nd = :vd) AND (#nts > :vts)',
            ProjectionExpression= 'time_stamp,event_type,country,tablet,mobile,desktop')

ERROR: An error occurred (ValidationException) when calling the Query operation: 
One or more parameter values were invalid: Condition parameter type does not match schema type

I believe this error may be related to the data type of time_stamp being a string and not the Decimal() format that dynamo uses to represent numbers.


Solution

  • You have to use & not and.

    resp = table.query(
                KeyConditionExpression=Key('domain').eq(domain) & Key('time_stamp').between(start,end),
                ProjectionExpression= 'time_stamp,event_type,country,tablet,mobile,desktop')
    

    This is where the AWS docs say this, but it's kind of buried in there.