简体   繁体   中英

Python - How to query DynamoDB on GSI using primary and sort key

Well, as the title suggest I want to query on my DynamoDB table using GSI with the primary key and sort key (both from the GSI). I tried some ways to do it, but any success.

I have a table with the url-date-index , the url is the primary key from from the GSI, and the date is the sort key.

I tried the following:

  1. Using KeyConditionExpression with & comparator:

    This one retrieved me the error: TypeError: expected string or bytes-like

boto3.resource('dynamodb').Table('table').query(
    IndexName='url-date-index',
    KeyConditionExpression=conditions.Key('url')).eq(url) & conditions.Key('date')).eq(date)
)
  1. Using KeyConditionExpression and FilterExpression :

    This retrieved the following error: Filter Expression can only contain non-primary key attributes

boto3.resource('dynamodb').Table('table').query(
    IndexName='url-date-index',
    KeyConditionExpression=conditions.Key('url')).eq(url),
    FilterExpression=conditions.Key('date')).eq(date)
)
  1. Using ExpressionAttributeNames , ExpressionAttributeValues and KeyConditionExpression :

    This returned anything, even not the item that matches the url and date on the table.

boto3.resource('dynamodb').Table('table').query(
    IndexName='url-date-index',
    ExpressionAttributeNames={
        '#n0': 'url',
        '#n1': 'date'
    },
    ExpressionAttributeValues={
        ':v0': url,
        ':v1': date
    },
    KeyConditionExpression='(#n0 = :v0) AND (#n1 = :v1)'
)

Does anyone know what I'm doing wrong or what I can do to make this work.

In your particular use-case, you'll want to use ExpressionAttributeNames since your attribute names url and date are reserved words in DynamoDB .

The DynamoDB docs on querying secondary idnexes gives an example of a properly structured query, which we can apply to your situation:

Using this as a guide, we can construct what the arguments to your query operation should look like. For example

 {
    "TableName": "table",
    "IndexName": "url-date-index",
    "KeyConditionExpression": "#pk = :pk And #sk = :sk",
    "ExpressionAttributeNames": {"#pk":"url","#sk":"date"},
    "ExpressionAttributeValues": {":pk": {"S":url},":sk": {"S":date}}}
}

If this still doesn't work for you, consider checking out the NoSQL Workbench For DynamoDB . Among it's many useful features, it has an Operation Builder that helps you construct DynamoDB operations using a graphical interface. You can even run the operation against your live database. Once you have the operation working as you want, the tool can then translate the operation into a complete Phython, Javascript(Node) or Java code sample, which you can use to see how the operation is constructed.

query is a function with some named arguments ( IndexName , KeyConditionExpression , ...).

Let's try to call the function with named arguments as a normal function:

boto3.resource('dynamodb').Table('table').query(
    IndexName='url-date-index', 
    KeyConditionExpression=conditions.Key('url')).eq(url) & conditions.Key('date')).eq(date)
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM