I am trying to do a batch_get_item to request multiple items from a table. I am following the PHP example in the DynamoDB documentation, but I am not getting the results I'm expecting.
Following is the code:
$batch_array = array ();
$batch_array[]= array ('HashKeyElement' =>
array( AmazonDynamoDB::TYPE_STRING => 'V1L3M5O5L1W8R5B6D2Q1S8V0B3R8M7A6R0X0'));
$options = array (
'RequestItems' => array(
'profile_dev' => array (
'Keys' => $batch_array
)
)
);
$result = $this->db->batch_get_item($options);
Instead of getting the data, I am getting a very long response, and I'm including the relevant information from the tail end of it:
[x-aws-body] => {"RequestItems":{"profile_dev":{"Keys":[{"HashKeyElement":{"S":"V1L3M5O5L1W8R5B6D2Q1S8V0B3R8M7A6R0X0"}}]}}} ) [body] => CFSimpleXML Object ( [__type] => com.amazon.coral.validate#ValidationException [message] => One or more parameter values were invalid: The provided key size does not match with that of the schema ) [status] => 400 ) )
The hashKey for this table is a string. It has a rangeKey, but I am using the hashKey so I can get all the rows matching the hashKey. What am I missing?
The DynamoDB documentation (and SDK samples) have colossal bugs in them. The documentation, and actual SDK code, make use only of the hashKeyElement, but in fact if a table has both a hashKey AND a rangeKey, both must be used.
When I used both the hashKey and the rangeKey, the call worked.
Get (or batch get) requires you to completely define the key of all items you are getting. If you want to retrieve all rows with the same hashKey using a single call, it seems like you're looking for Query.
You don't need to use BatchGet, you should be using Query. Here is an example using the PHP SDK to get all items with the HASH key 'YourHashKey' on table 'YourTable'
// Instantiate the class
$dynamodb = new AmazonDynamoDB();
$response = $dynamodb->query(array(
'TableName' => 'YourTable',
'HashKeyValue' => array( AmazonDynamoDB::TYPE_STRING => 'YourHashKey' ),
));
Reference: http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/LowLevelPHPQuerying.html
Related
Wordpress 5.3.2 and PHP 7.2 on localhost.
I'm sending a Twilio sms, and capturing the response from Twilio, which is JSON.
I want to store the response, because in it are all kinds of goodies, like the send date-time stamp.
When I make a test file, and print_r the response, it is a rather large JSON object. Not sure I should even post it here, at 11,568 characters. Here's a partial output (Acct values have been slightly altered):
Twilio\Rest\Api\V2010\Account\MessageInstance Object
(
[_media:protected] =>
[_feedback:protected] =>
[version:protected] => Twilio\Rest\Api\V2010 Object
(
[_accounts:protected] =>
[_account:protected] => Twilio\Rest\Api\V2010\AccountContext Object
(
[_addresses:protected] =>
[_applications:protected] =>
[_authorizedConnectApps:protected] =>
[_availablePhoneNumbers:protected] =>
[_calls:protected] =>
[_conferences:protected] =>
[_connectApps:protected] =>
[_incomingPhoneNumbers:protected] =>
[_keys:protected] =>
[_messages:protected] => Twilio\Rest\Api\V2010\Account\MessageList Object
(
[version:protected] => Twilio\Rest\Api\V2010 Object
*RECURSION*
[solution:protected] => Array
(
[accountSid] => AC3365f6c6dddaac48edfb902a3e1b8688d
)
[uri:protected] => /Accounts/AC3365f6c6dddaac48edfb902a3e1b8688d/Messages.json
)
[_newKeys:protected] =>
(etc., etc...)
My test code looks like this:
$data['numbers'] = array( "9541234567");// phone numbers of sms recipients. Just one for now.
$count = array();
for($i=0;$i<count($data['numbers']);$i++){
$args = array(
'number_to' => $data['numbers'][$i],
'message' => "This is a test.\n",
);
$sent = twl_send_sms( $args );
echo "<pre>";
print_r($sent);//This line outputs that beautiful, robust JSON string I am after.
echo "</pre>";
}
...so far, so good. The Twilio sms sends, and Twilio gives me a nice large response in JSON format.
Now, I transfer my code to the larger, production context, and I want to capture that 11,568 character JSON object, and store it in a table (by means of update). I think it should be a TEXT type, which is probably correct.
Here is my slightly revised code for production:
$data['twilio_response'] = twl_send_sms( $args ); //This sends the sms, captures a Twilio response into an array element.
$table = $wpdb->prefix . "npf_notifications";
$data['notification-update'] = $wpdb->update(
$table,
array('twilio_response' => $data['twilio_response']),
array('id' => $data['notifications-insert']['id']),
array('%s'),
array('%s')
);
$data['notification-update-query'] = $wpdb->last_query; // this records the query in an array element, so I can examine it.
Unfortunately for me, I don't get anything near as complete as the raw JSON from my test script. Instead, my Twilio response JSON looks like this:
notification-update-query = UPDATE `xsdslp_npf_notifications` SET `twilio_response` = '[Twilio.Api.V2010.MessageInstance accountSid=AC3365f6c6dceec35edfb902a3e1b8688d sid=SMfeb33b00895e455091445e4901547e70]' WHERE `id` = '5e092437a6037_1577657399'
...and the value of the array element to which I assign my Twilio response data looks like (after printing it out using javascript):
$data['twilio_response'] = [Twilio.Api.V2010.MessageInstance accountSid=AC3365f6c6ddaac48edfb902a3e1b8688d sid=SMfeddaac485e455091445e4901547e70]
It looks like the MySQL update (or insert) isn't the problem, but the JSON response string is being shortened in my array element variable. Can someone out there tell me what I'm doing wrong?
looks like you need to use json_encode() on $data['twilio_response'] first, because the returned object from twl_send_sms is not a JSON string, but a PHP object. Alternatively you can use serialize()
I have got this mongoDB query:
db.b_activity.find(
{token_id:"71e32267108b163ccdd3f59ba06c66674b295499"},
{activity_log:{$slice: -1}}
).pretty();
It gets all the desired results in the mongoDB terminal, but when I write the same query in PHP, it fetches the complete array every time.
MY PHP query:
$get_current_activity = $this->mongo_b_employee->b_activity->findOne(
array('token_id'=>$token_id),
array("activity_log" => array('$slice' => -1))
);
Any suggestions where I am doing something wrong?
PS: I am just trying to access the last array element.
The signature for MongoDB\Collection::findOne() is slightly different from the "shell". It requires the "projection" key in the $options as the second argument:
$get_current_activity=$this->mongo_b_employee->b_activity->findOne(
array('token_id'=>$token_id),
array(
"projection" => array( "activity_log" => array('$slice' => -1) )
)
)
I was successful in deleting documents using other fields but could not delete using "_id" field. The PHP page says that the id should be a string (which it is by default), but what I was trying to do is, giving an id of my own which is an integer, and am doing the following:
This is my document structure:
$document = array (
'_id' => new MongoInt32(1),
'cust_id' => 'abc124'
)
This is how I am trying to delete:
$collection->remove(array('_id' => new MongoId(1)), true);
But this is giving me an error. PHP php manual says:
"To remove a document based on its ID, you need to ensure that you pass the ID as a MongoID object rather than just a string:"
But my id is a int and I cant figure out the process to delete the document referenced by the id.
Your help would be appreciated. Thank You.
You've used a normal integer (MongoInt32) as _id field. And MongoInt32 is not the same as MongoID. They are two different classes. You are suppose to delete it with:
$collection->remove( array( '_id' => new MongoInt32(1) ) );
Additional Information:
MongoId is used as value for an _id field if you don't set a value yourself, such as with:
$collection->insert( array( 'cust_id' => 'abc124' ) );
If you retrieve this document, and var_dump() that you will see:
array(2) {
'_id' =>
class MongoId#6 (1) {
public $$id =>
string(24) "51ee74e944670a09028d4fc9"
}
'cust_id' =>
string(6) "abc124"
}
The note in the docs mean that you can't remove that document now with:
$collection->remove( array( '_id' => '51ee74e944670a09028d4fc9' ) );
But instead you will need to use:
$collection->remove( array( '_id' => new MongoID( '51ee74e944670a09028d4fc9' ) ) );
As last point I'd like to raise that you don't really have to use new MongoInt32(1) in the first place, you can just use:
$document = array (
'_id' => 1,
'cust_id' => 'abc124'
);
You only need MongoInt32/MongoInt64 in case you're on a 32-bit platform (or Windows) and need to deal with large numbers.
This should work:
$collection->deleteOne( array( '_id' => new MongoDB\BSON\ObjectId ($_id )) );
"To remove a document based on its ID, you need to ensure that you pass the ID as a MongoID object rather than just a string:"
Normally what the PHP manual states is true but not for you. You have changed the type of your _id to something other than an ObjectId (aka a MongoId).
With this in mind you need to search by that other object which is a MongoInt32:
$db->collection->remove(array('_id'=>new MongoInt32(1)))
In my controller I have the following lines
$request = Yii::$app->request;
print_r($request->post());
echo "version_no is ".$request->post('version_no',-1);
The output is given below
Array
(
[_csrf] => WnB6REZ6cTAQHD0gAkoQaSsXVxB1Kh5CbAYPDS0wOGodSRANKBImVw==
[CreateCourseModel] => Array
(
[course_name] => test
[course_description] => kjhjk
[course_featured_image] =>
[course_type] => 1
[course_price] => 100
[is_version] => 1
[parent_course] => test
[version_no] => 1
[parent_course_id] => 3
[course_tags] => sdsdf
)
)
version_no is -1
So here the return value of post() contains the version_no.But when it is called as $request->post("version_no"), it is not returning anything (or $request->post("version_no",-1) returns the default value -1).
As per Yii 2.0 docs, the syntax is correct and should return the value of post parameter.
But why is it failing in my case.The post array has the parameter in it.But the function is not returning when called for an individual parameter value.
your parameters are in $_POST['CreateCourseModel']['version_no'] etc. with $request->post('version_no',-1) you trying to get $_POST['version_no'] which is not defined so it returns you -1. So to get version_no use
$data = $request->post('CreateCourseModel');
print_r($data['version_no']);
You can access nested $_POST array elements using dot notation:
\Yii::$app->request->post('CreateCourseModel.version_no', -1);
Model properties are grouped like that for massive assignment that is done via $model->load(Yii::$app->request->post()).
Depending on your needs maybe it's better use default value validator like that:
['version_no', 'default', 'value' => -1],
I'm querying a DynamoDB table using the method described here in the AWS PHP developer guide.
The array that I pass to the Dynamo connection looks like the following:
Array(
[ConsistentRead] => false
[TableName] => bbq_lol_test
[KeyConditions] => Array(
[stinky_cheese] => Array(
[ComparisonOperator] => EQ
[AttributeValueList] => Array(
[S] => camembert)
)
)
)
As you can see, it's in the exact format that the example uses, with the exception of the Type enum (which is just a string).
When executing $connection->query with the above array as an argument, I get the following exception:
Guzzle\Service\Exception\ValidationException:
Validation errors: [KeyConditions][stinky_cheese][AttributeValueList][S][AttributeValue] must be of type object
Which is odd, because the array in the stack trace appears to be fine:
Aws/Common/Client/AbstractClient.php(103): Guzzle\Service\Client->__call("Query", array(array("ConsistentRead" => false, "TableName" => "bbq_lol_test", "KeyConditions" => array("stinky_cheese" => array("ComparisonOperator" => "EQ", "AttributeValueList" => array("S" => "camembert"))))))
I DO have an index on the stinky_cheese field (since I'm using query). I'm probably doing something daft, but I can't seem to figure it out now. Any help would be appreciated - thanks!
There were two problems.
First, AttributeValueList should be an array of arrays, not a single array, going from this:
[AttributeValueList] => Array([S] => camembert)
To this:
[AttributeValueList] => Array(Array([S] => camembert))
Since it's possible to add more stuff in there, like so:
[AttributeValueList] => Array(Array([S] => camembert), Array([S] => bleu))
The second problem was that I always have to query using the primary hash key, which I was not doing.