I want to update data using 'typeId', 'type_id' is not a primary key.
While this code is work, if we use other primary key.
Unable to update record.
getting following error :
{"__type":"com.amazon.coral.validate#ValidationException","message":"The provided key element does not match the schema"}
$response = $this->dbo->updateItem([
'TableName' => $this->tableName,
'Key' => [
'typeId' => ['S' => "qtwr234"]
],
'ExpressionAttributeValues' => [
':val1' => ['N' => '1']
],
'UpdateExpression' => 'set count = :val1',
'ReturnValues' => 'ALL_NEW'
]);
According the error message you're receiving
This error occurs when your key (hash / primary key) doesn't not match in parameters your passing to update the data in table.
Solution :
Run listTables commands and check for key element you created while creating elements.
Now, replace that key element in query parameters.
Thanks
Related
I have a table that has a column called "items", but not all rows have it, so I want to scan all rows that have "items".
Something like:
$resposta = $clientDB->scan(array(
'TableName' => 'tableName',
'Key' => [
'items' => ['S' => 'exists']
]
));
But I can't figure out how to do it...
The table has 10000 rows, but only 10 of them have "items", and I want to get only these 10 rows.
Edit:
As Seth Geoghegan pointed below, it was necessary create a global secondary indexes on the attribute i wanted to filter.
I ended up here:
$params = [
'TableName' => 'tableName',
'FilterExpression' => "attribute_exists(items)"
];
OR
$params = [
'TableName' => 'tableName',
'FilterExpression' => 'items != :null',
'ExpressionAttributeValues' => [
':null' => null,
],
];
But both didnt worked... First one seens necessary ExpressionAttributeValues to be setup and the second the php stop working with no error logs.
This is a perfect use case for global secondary indexes (GSI)!
You can create a GSI on the items attribute. Items with the items attribute defined will get projected into the GSI. Importantly, items that do not contain this attribute will not be in the index. You could then query the GSI and retrieve the items you're after.
Well, after some effort, i found a way though:
$resposta = $clientDB->scan(array(
'TableName' => 'tableName',
'FilterExpression' => "attribute_exists(items)"
));
After i created another global secondary index (GSI) for "items" (pointed by Seth Geoghegan), i just needed to add in the scan function the FilterExpression the "attribute_exists(items") and it worked.
I am using laravel's Model::create() function to create a new entry in my database, but the array i'm passing into the function fails because it deletes one of the rows.
This is my array All static. This also matches what my database table looks like.
$data = [
'terminal_id' => 222,
'batch_id' => 1,
'transactiondate' => '2323',
'store' => '2323',
'hostcode' => '2323',
'pan' => '2323',
'operation' => '2323',
'posdatacode' => '2323',
'amount' => '2323',
'currency' => '2323',
'acquirer' => '2323',
'scheme' => '2323',
'attemptsconn' => '2323',
'transactionresult' => '2323',
'merchantcode' => '2323',
'terminal' => '2323'
];
And the line to insert it into the database
Transaction::create($data);
SQL error code when running this code:
SQLSTATE[HY000]: General error: 1364 Field 'amount' doesn't have a default value (SQL: insert into `transactions` (`terminal_id`, `batch_id`, `transactiondate`, `store`, `hostcode`, `pan`, `operation`, `posdatacode`, `currency`, `acquirer`, `scheme`, `attemptsconn`, `transactionresult`, `merchantcode`, `terminal`, `updated_at`, `created_at`)
Now, if you look through the code, you'll notice the amount section of the array has gone missing.
What have i tried:
Formatting the entry code to Transaction::create(['row' => 'value']) instead of what i was doing. This returns same result.
Creating a new transaction by doing new Transaction and then $transaction->value to insert the data. THIS WORKS.
I must be missing something obvious since this doesn't work. Please help me out.
Error:
"Field 'amount' doesn't have a default value"
comes due to
you can not set a default value for amount field in the database when the field amount is missing from the array, error throw.
So set the default value or set Null.
As Liam suggested the "amount" field was not in my $fillable array in the Model.
Code works flawlessly after inserting that value into the array.
Please upvote Liam's comment if you had an error like this, no need to answer this further.
Its updating data if session is exists fine.
But when session is not exists its create a new row.At this stage , i dont want to do any action.
$sessionId = $params['session_id'];
$response = $this->dbo->updateItem([
'TableName' => $this->tableName,
'Key' => [
'id' => [ 'S' => $sessionId]
],
'ExpressionAttributeValues' => [
':val1' => ['S' => date('Y-m-d H:i:s')]
],
'UpdateExpression' => 'set sessionEnd = :val1',
'attributeExists' => 'id',
'ReturnValues' => "UPDATED_NEW"
]);
The update item API would create the new item if it doesn't exist. You can use ConditionExpression to stop creating the new item.
Edits an existing item's attributes, or adds a new item to the table
if it does not already exist.
This means only if the id is already present, the update operation will happen. Also, it will stop creating the new item.
'ConditionExpression' => 'attribute_exists(id)',
If the key is not found, the API throws the below exception.
"code": "ConditionalCheckFailedException",
I am parsing an external JSON datasource which gives me list of Bus Stop codes and corresponding street names.
Data is presented to me in this format:
BusStop01 Street01 Description22 Latitude31 Longitude44
BusStop12 Street05 Description72 Latitude13 Longitude32
BusStop22 Street34 Description28 Latitude43 Longitude21
...
I am able to parse the JSON and use the AWS PHP SDK and store this in DynamoDB in the same format with BusStop a the primary key. Here's the relevant section of my code:
$putResponse = $client->putItem([
'TableName' => 'TABLEDUMMY01',
'Item' => [
'BusStopCode' => ['N' => $BusStopCode ], // Primary Key
'RoadName' => ['S' => $RoadName ],
'Description' => ['S' => $Description ],
'Latitude' => ['S' => strval($Latitude) ],
'Longitude' => ['S' => strval($Longitude) ]
]
]);
What I really want to achieve is to store the same data in this format using StreetName as the Primary Key:
StreetName01, BusStop01, BusStop33, BusStop43...
StreetName02, BusStop23, BusStop29, BusStop67...
NOTE: The external datasource gives me only 50 values in one API call, hence I need to be able to append/push new BusStop IDs in to existing Street Names on DynamoDB
I am beating my head on the table for too long with this one...
I have two MongoDB collections: "chatroom" and "users". The "chatroom" collection has "user_id" key pointing to a specific single user in "users" collection.
I am trying to fetch the chatroom with a user using the $lookup aggregate query, what I currently have is this one:
$this->mongo->chatroom->aggregate(
array('$lookup' => array(
'from' => 'users',
'localField' => 'user_id',
'foreignField' => '_id',
'as' => 'user'
))
);
However, this returns an empty "user" field in the collection. The weird thing is that if I try to replace the "_id" with custom "uid" set to the value of _id.$id, it works as expected:
$this->mongo->chatroom->aggregate(
array('$lookup' => array(
'from' => 'users',
'localField' => 'user_id',
'foreignField' => 'uid', // uid = _id.$id
'as' => 'user'
))
);
I figured out the problem is that "_id" is ObjectId while "user_id" is a String. But I don't know how to deal with the problem nicely...
To answer my own question, I went around the problem by making "user_id" an instance of a "MongoId" class instead of a plain string. Basically, I store "user_id" as:
$mongoObject["user_id"] = new MongoId($this->user_id);
Another solution would probably be decorating the objects with "uid" field with a value equal to "_id.$id".