John
John

Reputation: 1947

How to query over specific value in dictionary in dynamoDB?

I have a table stored in dynamoDB which exemplary dictionary is the following:

 {event': 'A',
  'timestamp': '2017-10-15 16:20:47,009',
  'message': 'AAA'},
 {event': 'B',
  'timestamp': '2018-10-15 16:20:47,009',
  'message': 'BBB'},
 {event': 'A',
  'timestamp': '2019-10-15 16:20:47,009',
  'message': 'BBB'},
 {event': 'B',
  'timestamp': '2020-10-15 16:20:47,009',
  'message': 'AAA'},

I would like to do to things:

  1. Query over timestamp - to have only dictionaries after year 2018
  2. Query over message - to have only dictionaries for which message == AAA

Let's focus on querying over message:

I used the following code to load the table:

import boto3
client = boto3.client("dynamodb", region_name="eu-central-1")
session = boto3.Session(profile_name="myprofile")
resource = session.resource("dynamodb", region_name="eu-central-1")
table = resource.Table("mytable")

The main problem I have is that when I'm running query code:

response = table.query(
    KeyConditionExpression="message = :message",
    ExpressionAttributeValues={":message": "AAA"},
)

I obtain the following error:

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

I read something about this error, and people are saying that I can scan the table (which is impossible in my situation. since my whole table is enormous) or use secondary index (which unfortunately I couldn't understand what it means). Could you please give me a hand how can I solve this problem?

EDIT

After answer I tried to do:

response = table.query(
    KeyConditionExpression="message = :message",
    FilterExpression="#ts >:timestamp",
    ExpressionAttributeValues={":message": "AAA",
    ":timestamp": "2018-01-01 00:00:00"},
      ExpressionAttributeNames={
    "#ts": "timestamp"
  }
)

But I got the error: ClientError: An error occurred (ValidationException) when calling the Query operation: Query condition missed key schema element: event

Without usage of ExpressionAtrributeNames the error is identical

Upvotes: 1

Views: 878

Answers (1)

Abdullah Ilgaz
Abdullah Ilgaz

Reputation: 739

To query a table in DynamoDB based on the value of a specific attribute, you need to specify that attribute in the KeyConditionExpression parameter of the query method.

The KeyConditionExpression parameter defines the conditions that the items in the table must meet in order to be returned by the query.

Your example

response = table.query(
    KeyConditionExpression="message = :message",
    ExpressionAttributeValues={":message": "AAA"},
)

In this sample, only items with a message attribute equal to "AAA" should be returned by the query.

Solution

response = table.query(
    KeyConditionExpression="event = :event and message = :message",
    FilterExpression="#ts > :timestamp",
    ExpressionAttributeValues={
        ":event": "A",
        ":message": "AAA",
        ":timestamp": "2018-01-01 00:00:00",
    },
    ExpressionAttributeNames={
        "#ts": "timestamp",
    },
)

This example shows you that:

  1. FilterExpression parameter specifies that only items with a timestamp attribute that is greater than "2018-01-01 00:00:00" should be returned by the query. (We changed timestamp keyword to ts for your error.)

  2. KeyConditionExpression parameter specifies that only items with message attribute equal to "AAA" and event attribute equal to "A" should be returned by the query.

  3. ExpressionAttributeValues parameter defines the values that will be used in the KeyConditionExpression and FilterExpression parameters.

Hope it helps.

Upvotes: 2

Related Questions