Unable to PUT to DynamoDB from a Python Lambda function - amazon-web-services

Im using a Lambda function to get and put data to DynamoDB.
I am able to put a new item into my table, but when I try to pass anything other than KEY I get the following error:
An error occurred (ValidationException) when calling the UpdateItem operation:
The provided key element does not match the schema
This works (with key only):
"body": "{\"TableName\":\"myExampleTableName\",\"Key\":{\"id\": {\"S\": \"SomeID\"}}}"
This throws error(with key and some data):
"body": "{\"TableName\":\"myExampleTableName\",\"Key\":{\"id\": {\"S\": \"SomeID\"},\"Data\": {\"S\": \"MyDataExampleData\"}}}"
Although it seems to be the same syntax as the example shows here.
Anybody see what I am doing wrong?
Here's the my body in a more readable way:
{
"TableName":"myExampleTableName",
"Key":{
"id": {"S": "SomeID"},
"Data": {"S": "MyDataExampleData"}
}
}

The "Data" field inside the "Key" doesn't seem right. It would be easier to understand if we had the actual code and the schema of the table you're trying to put.
This is an example using python, where you can see that there's no "Key" attribute, but "Item" (I'm assuming you're using python based on the doc you've sent)
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.Python.03.html
response = table.put_item(
Item={
'year': year,
'title': title,
'info': {
'plot': plot,
'rating': rating
}
}
)

Related

AWS Quicksight parseJson function not working with redshift

How to fix parseJson function error in AWS Quicksight?
I have a json column in AWS redshift called discount_codes of type varchar. The data looks like this:
{'code': 'blabla', 'amount': '12.00', 'type': 'percentage'}
I want to have a seperate column for 'code' in Quicksight. There is a function for this called parseJson. The formular should look like this.
parseJson({discount_codes}, "$.code")
Unfortunately it is not working and giving me the following error:
[Amazon](500310) Invalid operation: JSON parsing error Details: ----------------------------------------------- error: JSON parsing error code: 8001 context: invalid json object {'code': 'blabla', 'amount': '12.00', 'type': 'percentage'}
Any idea how to fix this?
I could fix it by myself. The json column had single quotation marks. I replaced them by normal ones. Now the data looks like this:
{"code": "blabla", "amount": "12.00", "type": "percentage"}
parseJson works now.

Adding new attribute to DynamDB table with updateItem

I have table already and I want to add a new attribute to that table.
I am trying to do that with the update_item functionality of dynamDB.
use case: Bid table holds details on the bid of the product. The user accepts the bid, once the bid is accepted, have to add a few attributes to that record like the user information. Not sure if it is the right way or should I have a new table for this.
pratition key is : Pickup,
sort key is : DropOff
A Demo example that I am trying currently
currently trying to alter the same table and facing the error.
import json
import boto3
def lambda_handler(event, context):
dynamo_client = boto3.resource('dynamodb')
users = dynamo_client.Table('LoadsandBids')
item = event['body']
print("Fuirst")
users.update_item(
Key={
'Pickup': event['body']['Pickup'],
'DropOff' : event['body']['DropOff']
},
UpdateExpression='SET #attr1 = :val1',
ExpressionAttributeNames={'#attr1': 'new_field'},
ExpressionAttributeValues={':val1': event['body']['new']},
ReturnValues='UPDATED_NEW'
)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
getting an error:
"An error occurred (ValidationException) when calling the UpdateItem operation: The provided key element does not match the schema",
Could anyone help me out of this and also suggest it I my approach is good or not?

Not able to add data into DynamoDB using API gateway POST method

I made a Serverless API backend on AWS console which uses API Gateway, DynamoDB, Lambda functions.
Upon creation I can add the data in dynamoDB online by adding a JSON file, which looks like this:
{
"id": "4",
"k": "key1",
"v": "value1"
}
But when I try to add this using "Postman", by adding the above JSON data in the body of POST message, I get a Positive return (i.e. no errors) but only the "id" field is added in the database and not the "k" or "v".
What is missing?
I think that you need to check on your Lambda function.
As you are using Postman to do the API calls, received event's body will be as follows:
{'resource':
...
}, 'body': '{\n\t"id": 1,\n\t"name": "ben"\n
}', 'isBase64Encoded': False
}
As you can see:
'body': '{\n\t"id": 1,\n\t"name": "ben"\n}'
For example, I will use Python 3 for this case, what I need to do is to load the body into JSON format then we are able to use it.
result = json.loads(event['body'])
id = result['id']
name = result['name']
Then update them into DynamoDB:
item = table.put_item(
Item={
'id': str(id),
'name': str(name)
}
)

Boto3 athena query without saving data to s3

I am trying to use boto3 to run a set of queries and don't want to save the data to s3. Instead I just want to get the results and want to work with those results. I am trying to do the following
import boto3
client = boto3.client('athena')
response = client.start_query_execution(
QueryString='''SELECT * FROM mytable limit 10''',
QueryExecutionContext={
'Database': 'my_db'
}.
ResultConfiguration={
'OutputLocation': 's3://outputpath',
}
)
print(response)
But here I don't want to give ResultConfiguration because I don't want to write the results anywhere. But If I remove the ResultConfiguration parameter I get the following error
botocore.exceptions.ParamValidationError: Parameter validation failed:
Missing required parameter in input: "ResultConfiguration"
So it seems like giving s3 output location for writing is mendatory. So what could the way to avoid this and get the results only in response?
The StartQueryExecution action indeed requires a S3 output location. The ResultConfiguration parameter is mandatory.
The alternative way to query Athena is using JDBC or ODBC drivers. You should probably use this method if you don't want to store results in S3.
You will have to specify an S3 temp bucket location whenever running the 'start_query_execution' command. However, you can get a result set (a dict) by running the 'get_query_results' method using the query id.
The response (dict) will look like this:
{
'UpdateCount': 123,
'ResultSet': {
'Rows': [
{
'Data': [
{
'VarCharValue': 'string'
},
]
},
],
'ResultSetMetadata': {
'ColumnInfo': [
{
'CatalogName': 'string',
'SchemaName': 'string',
'TableName': 'string',
'Name': 'string',
'Label': 'string',
'Type': 'string',
'Precision': 123,
'Scale': 123,
'Nullable': 'NOT_NULL'|'NULLABLE'|'UNKNOWN',
'CaseSensitive': True|False
},
]
}
},
'NextToken': 'string'
}
For more information, see boto3 client doc: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/athena.html#Athena.Client.get_query_results
You can then delete all files in the S3 temp bucket you've specified.
You still need to provide s3 as temporary location for Athena to save the data although you want to process the data using python. But you can page through the data as tuple using Pagination API. please refer to the example here. Hope that helps

Getting response from AWS Lambda function to AWS Lex bot is giving error?

I have created one AWS Lex bot and I am invoking one lambda function from that bot. When testing the lambda function I am getting proper response but at bot I am getting below error:
An error has occurred: Received invalid response from Lambda: Can not
construct instance of IntentResponse: no String-argument
constructor/factory method to deserialize from String value
('2017-06-22 10:23:55.0') at [Source: "2017-06-22 10:23:55.0"; line:
1, column: 1]
Not sure, what is wrong and where I am missing. Could anyone assist me please?
The solution to above problem is that we need to make sure response returned by lambda function, to be used at AWS lex chat bot should be in below format:
{
"sessionAttributes": {
"key1": "value1",
"key2": "value2"
...
},
"dialogAction": {
"type": "ElicitIntent, ElicitSlot, ConfirmIntent, Delegate, or Close",
Full structure based on the type field. See below for details.
}
}
By this, chat bot expectd DialogAction and corresponding elements in order to process the message i.e. IntentResponse.
Reference: http://docs.aws.amazon.com/lex/latest/dg/lambda-input-response-format.html
no String-argument constructor/factory method to deserialize from String value
You are getting this error because you must be passing string values in the response of lambda function. You have to pass a predefined json object blueprint in the response.
Because the communication between Lex and Lambda is not simple value passing like normal functions. Amazon Lex expects output from Lambda in a particular JSON format and data is sent to Lambda in a particular JSON. The examples are here: Lambda Function Input Event and Response Format.
And just copying and pasting the blueprint won't work because in some fields you have choose between some predefined values and in some fields you have to entry valid input.
For example in,
"dialogAction": {
"type": "Close",
"fulfillmentState": "Fulfilled or Failed",
"message": {
"contentType": "PlainText or SSML",
"content": "Thanks, your pizza has been ordered."
}
}
you have assign a value "Fulfilled" or "Failed" to field 'fulfillmentState'. And same goes for 'contentType'.