DynamoDB PutItem does not create new item - amazon-web-services

I use a lambda to detect if there is any isActive record in my table and put_item to update the id if there is.
For example, I have a placeholder record with ID 999999999, if my table query detected there's an active record (isActive = True), it will put_item with the real session_id and other data.
Table record:
My lambda has the following section (from my cloudwatch the if...else statement is working as intended to verify the logic). Please ignore indentation hiccups when i copy and paste, the code runs with no issue.
##keep "isActive = True" when there's already an active status started from other source, just updating the session_id to from 999999999 to real session_id
else:
count_1 = query["Items"][0]["count_1"] <<< from earlier part of code to retrieve from current count_1 value from the table.
print(count_1) << get the right '13' value from the current table id = '999999999'
table.put_item(
Item={
'session_id': session_id,
'isActive': True,
'count_1': count_1,
'count_2': count_2
},
ConditionExpression='session_id = :session_id AND isActive = :isActive',
ExpressionAttributeValues={
':session_id': 999999999,
':isActive': True
}
)
However my table is not getting new item nor the primary key session_id is updated. Table still stays as the image above.
I understand from the documentation that
You cannot use UpdateItem to update any primary key attributes.
Instead, you will need to delete the item, and then use PutItem to
create a new item with new attributes.
but even if put_item is not able to update primary key, at least I am expecting a new item being created from my code when there isn't any error code thrown?
Does anybody know what is happening? thanks

I resolved it with different specification for ConditionExpression. Did multiple troubleshooting ways and pinpoint the issue comes from ConditionExpression:
What i did instead -
add imports of boto3.dynamodb.conditions import Key & Attr
and use ConditionExpression with ConditionExpression=Attr("session_id").ne(999999999)
and delete old id item
table.delete_item(
Key={
'session_id': 999999999
}
)
Other conditions available here https://boto3.amazonaws.com/v1/documentation/api/latest/reference/customizations/dynamodb.html#ref-dynamodb-conditions
If anyone has any other better and easier way would like to learn

Related

how to perfom a getItem and updateItem in a transaction with dynamodb with go?

This is the fist time using dynamo and y dont know how to retrieve and record and also update the status of that record in a transaction.
I have a table "product" and I need to select one record with attribute1 = abc and isUsed = false and then update its status to isUsed = true.
Product
pk (hash)
attribute1
isUsed
123
abc
true
345
abc
false
456
abc
false
567
qwe
false
All de documentation talk about the use of transactionWriteItem and transactionGetItem but I don't know how to do the get and update in the same transacction. Is there a way to do this?
I need to do something like this:
find a record and use the pk of that record to update it.
twii := &dynamodb.TransactWriteItemsInput{
TransactItems: []*dynamodb.TransactWriteItem{
{
Get: &dynamodb.Get{
Item: av2,
TableName: aws.String(product),
ConditionExpression: aws.String("..."),
},
},
{
Update: &dynamodb.Update{
Item: av,
TableName: aws.String(activationTable),
ConditionExpression: aws.String("..."),
},
},
},
}
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html
Transactions can only read or write, not both.
You don't list your actual needs, but if I'm guessing right: you need to do a get (or query), manipulate the item client-side, then put the new version.
To ensure you're not overwriting some other thread's changes in between your read and write, you may want to use "optimistic locking" and have a version number or last modified timestamp on each item and issue a condition expression as part of the write to make sure it's still the same as when you got it. It's a common idiom.
Note that in DynamoDB a condition expression is a write feature, not a read feature. I noticed you used it in your pseudocode around the get. It's about enforcing the write happens only if a condition is satisfied (like that the timestamp hasn't changed).

Getting the list of approved items from status column in dynamodb

I am trying to query to my dynamodb using paginator.paginate.
Here is my code:
for page_1 in paginator.paginate(TableName=chroma_organization_data_table,
FilterExpression='#s = Approved',
ProjectionExpression="#s, organizationId",
ExpressionAttributeNames={'#s': 'status'}
):
print page_1
However, I get nothing returned back. I know there are several entries that are in the 'approved' states.
This is how my dynamodb returns data if there are no conditions on it (no FilterExpression)(example)
[{u'organizationId': {u'S': u'323454354525'}, u'status': {u'S': u'Approved'}}]
So clearly there is an entry where status is approved just when I use paginator, it doesn't work.
What can I do about this?
You cannot embed string literals in filter/condition expressions. You need to set an ExpressionAttributeValues map equal to { ":approved": "Approved" } and then update your filter expression to be #s = :approved.

AWS DynamoDB query with Key Condition Expression got an error: Query key condition not supported

The image below show my table's structure
And try to querying the list of item with Java code below:
QuerySpec qs = new QuerySpec()
.withKeyConditionExpression("RecordID >= :v_recordID")
.withFilterExpression("DeviceID = :v_deviceID")
.withValueMap(new ValueMap()
.withInt(":v_recordID", recordID)
.withString(":v_deviceID", deviceID)
);
I wanna to get items with RecordID greater than or equal 5, but it got an error:
Query key condition not supported
How to solve it, thanks in advance !
Check out link : http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html
The partition key equality test is required, and must be specified in the following format:
partitionKeyName = :partitionkeyval

IF statements in SQL Server triggers

I need to create a SQL Server trigger to block updates and deletes to a table Service.
This action should be done only to Service in which the column States sample data is "completed".
It should allow updates and deletes to Service in which the column States sample data is "active".
This is what I tried, I am having problems with doing the else operation (that is allowing updates to Service in which the column State sample data is "active").
CREATE TRIGGER [Triggername]
ON dbo.Service
FOR INSERT, UPDATE, DELETE
AS
DECLARE #para varchar(10),
#results varchar(50)
SELECT #para = Status
FROM Service
IF (#para = 'completed')
BEGIN
SET #results = 'An invoiced service cannot be updated or deleted!';
SELECT #results;
END
BEGIN
RAISERROR ('An invoiced service cannot be updated or deleted', 16, 1)
ROLLBACK TRANSACTION
RETURN
END
So if I understand you correctly, any UPDATE or DELETE should be allowed if the State column has a value of Active, but stopped in any other case??
Then I'd do this:
CREATE TRIGGER [Triggername]
ON dbo.Service
FOR UPDATE, DELETE
AS
BEGIN
-- if any row exists in the "Deleted" pseudo table of rows that WERE
-- in fact updated or deleted, that has a state that is *not* "Active"
-- then abort the operation
IF EXISTS (SELECT * FROM Deleted WHERE State <> 'Active')
ROLLBACK TRANSACTION
-- otherwise let the operation finish
END
As a note: you cannot easily return messages from a trigger (with SELECT #Results) - the trigger just silently fails by rolling back the currently active transaction

dynamodb - scan items where map contains a key

I have a table that contains a field (not a key field), called appsMap, and it looks like this:
appsMap = { "qa-app": "abc", "another-app": "xyz" }
I want to scan all rows whose appsMap contains the key "qa-app" (the value is not important, just the key). I tried something like this but it doesn't work in the way I need:
FilterExpression = '#appsMap.#app <> :v',
ExpressionAttributeNames = {
"#app": "qa-app",
"#appsMap": "appsMap"
},
ExpressionAttributeValues = {
":v": { "NULL": True }
},
ProjectionExpression = "deviceID"
What's the correct syntax?
Thanks.
There is a discussion on the subject here:
https://forums.aws.amazon.com/thread.jspa?threadID=164470
You might be missing this part from the example:
ExpressionAttributeValues: {":name":{"S":"Jeff"}}
However, just wanted to echo what was already being said, scan is an expensive procedure that goes through every item and thus making your database hard to scale.
Unlike with other databases, you have to do plenty of setup with Dynamo in order to get it to perform at it's great level, here is a suggestion:
1) Convert this into a root value, for example add to the root: qaExist, with possible values of 0|1 or true|false.
2) Create secondary index for the newly created value.
3) Make query on the new index specifying 0 as a search parameter.
This will make your system very fast and very scalable regardless of how many records you get in there later on.
If I understand the question correctly, you can do the following:
FilterExpression = 'attribute_exists(#0.#1)',
ExpressionAttributeNames = {
"#0": "appsMap",
"#1": "qa-app"
},
ProjectionExpression = "deviceID"
Since you're not being a bit vague about your expectations and what's happening ("I tried something like this but it doesn't work in the way I need") I'd like to mention that a scan with a filter is very different than a query.
Filters are applied on the server but only after the scan request is executed, meaning that it will still iterate over all data in your table and instead of returning you each item, it applies a filter to each response, saving you some network bandwidth, but potentially returning empty results as you page trough your entire table.
You could look into creating a GSI on the table if this is a query you expect to have to run often.