Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to choose what should be the field to be return in DynamoDB?

I am wondering if there is a way that i can choose what field should be included in the result of dynamodb query or scan. I try to use AttributesToGet

def filter_ga_account_by_email(self, email):
    response = Table.scan(
        FilterExpression=Attr('client_email').eq(email),
        AttributesToGet=['id'],
    )

    return response['Items']

and now i have this error : ClientError: An error occurred (ValidationException) when calling the Scan operation: Can not use both expression and non-expression parameters in the same request: Non-expression parameters: {AttributesToGet} Expression parameters: {FilterExpression}

like image 909
Alex Avatar asked Jun 17 '16 08:06

Alex


3 Answers

The easiest way is to add the projectionExpression parameter and specify the attributes that you want to return in a array of strings, a working example:

    const getProducts = (user) => {
                    var params = {
                        TableName: process.env.PRODUCTS,
                        ScanIndexForward: false,
                        KeyConditionExpression: 'user = :hkey',
                        ExpressionAttributeValues: {
                            ':hkey': user,
                        },
                        Limit: 200,
                        ProjectionExpression: ['internal_type', 'requested_at']
                };
     return dynamoClient.query(params).promise();
}
like image 120
fgonzalez Avatar answered Sep 22 '22 13:09

fgonzalez


sure,

you can use 'AttributesToGet':

client = boto3.client('dynamodb')

response = client.get_item(TableName='tbl_name', Key={'client_email':{'N':str(email)}}, AttributesToGet=['id'])

but please note:

This is a legacy parameter, for backward compatibility. New applications should use ProjectionExpression instead. Do not combine legacy parameters and expression parameters in a single call; otherwise, DynamoDB will return a ValidationException exception. This parameter allows you to retrieve attributes of type List or Map; however, it cannot retrieve individual elements within a List or a Map.

http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#API_Query_RequestSyntax

like image 29
Eyal Ch Avatar answered Sep 22 '22 13:09

Eyal Ch


The boto3 dynamodb docs note that you are not able to combine the "legacy" parts of the API (including the Select and AttributeToGet keywords arguments) with the newer API keyword arguments including KeyConditionExpression and ProjectionExpression). This is why you are getting the ValidationError. The correct way to only query certain attributes is using the ProjectionExpression keyword argument.

If you want to query for specific attributes only (while using the "new" keyword argument set), you can use the below code:

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

table = boto3.resource("dynamodb", region_name='us-east-2').Table(<table_name>

def filter_ga_account_by_email(self, email):
    response = table.scan(
        IndexName='client_email', # Include if client_email is an indexed field
        FilterExpression=Attr('client_email').eq(email), # Include if client_email is a non-indexed field
        KeyConditionExpression=Key('client_email').eq(email), # Include if client_email is an indexed field
        ProjectionExpression="id", # Comma-separated list of desired attributes, e.g., "id,client_id
    )

    return response['Items']

In response to your question about getting specific attributes, the ProjectionExpression is the best way to do this.

like image 44
Sam Jett Avatar answered Sep 21 '22 13:09

Sam Jett