I'm running into issues sending data to my DynamoDB. I have no idea what the issue is because it appears the program runs correctly, however I don't seem to have any data in my DB. I was able to create tables using Amazons tutorial, but when I follow this tutorial, I get a failed response if I try and put ALL the items, and a false success when it's only one item, as nothing is updated in the db.
Here's the code, I'm curious specifically if anyone knows a means to debug these kinds of issues.
<?php
// If necessary, reference the sdk.class.php file.
// For example, the following line assumes the sdk.class.php file is
// in an sdk sub-directory relative to this file
require_once('includes/backend.php');
// Instantiate the class
$dynamodb = new AmazonDynamoDB();
####################################################################
# Setup some local variables for dates
$one_day_ago = date('Y-m-d H:i:s', strtotime("-1 days"));
$seven_days_ago = date('Y-m-d H:i:s', strtotime("-7 days"));
$fourteen_days_ago = date('Y-m-d H:i:s', strtotime("-14 days"));
$twenty_one_days_ago = date('Y-m-d H:i:s', strtotime("-21 days"));
####################################################################
# Adding data to the table
echo PHP_EOL . PHP_EOL;
echo "# Adding data to the table..." . PHP_EOL;
// Set up batch requests
$queue = new CFBatchRequest();
$queue->use_credentials($dynamodb->credentials);
// Add items to the batch
$dynamodb->batch($queue)->put_item(array(
'TableName' => 'ProductCatalog',
'Item' => array(
'Id' => array( AmazonDynamoDB::TYPE_NUMBER => '101' ), // Hash Key
'Title' => array( AmazonDynamoDB::TYPE_STRING => 'Book 101 Title' ),
'ISBN' => array( AmazonDynamoDB::TYPE_STRING => '111-1111111111' ),
'Authors' => array( AmazonDynamoDB::TYPE_ARRAY_OF_STRINGS => array('Author1') ),
'Price' => array( AmazonDynamoDB::TYPE_NUMBER => '2' ),
'Dimensions' => array( AmazonDynamoDB::TYPE_STRING => '8.5 x 11.0 x 0.5' ),
'PageCount' => array( AmazonDynamoDB::TYPE_NUMBER => '500' ),
'InPublication' => array( AmazonDynamoDB::TYPE_NUMBER => '1' ),
'ProductCategory' => array( AmazonDynamoDB::TYPE_STRING => 'Book' )
)
));
echo "Item put in <b>Reply</b>" . "<br/>";
// Execute the batch of requests in parallel
$responses = $dynamodb->batch($queue)->send();
// Check for success...
if ($responses->areOK())
{
echo "The data has been added to the table." . PHP_EOL;
}
else
{
utdump($responses);
}
Thank you for your time
Try setting your region explicitly, e.g. for EU you need to call:
$myDynamoDbObject->set_region('dynamodb.eu-west-1.amazonaws.com');
It might also be that you have two tables in different regions, your application work with one of them and you trying to read (or track with web console) another one because of different default regions applied.
If you're tracking number of items in the table, keep in mind that it is not a real time figure, it is only updated every 6 hours or so. So the way use can ensure your item is indeed written by trying to read it back immediately after you receive the "OK" response for your put request.
Related
Finishing of my elgg plugin has come to some issues, after fixing my last question I have encountered another. Apperently I am misusing or misunderstanding the use of the Created time lower and upper functions in Elgg
With the code below:
$monthSpan = (30 * 24 * 60 * 60);
$startTime = time() - $monthSpan;
$MemberDifference = elgg_get_entities_from_relationship(array(
'relationship' => 'member', //get Members
'relationship_guid' => $group->guid, //get individual guid for use
'inverse_relationship' => true,
'type' => 'user', //users are returned
'limit' => 20,
'joins' => array("JOIN {$db_prefix}users_entity u ON e.guid=u.guid"),
'order_by' => 'u.name ASC',
'relationship_created_time_lower' => $startTime, //the furthest back it will reach
'relationship_created_time_upper' => time(), //possibly unneeded, but ensures the closest date is today
'count' => true,
));
Using this function, I built it upon my way to get all of the members in the associated group, theoretically it should now grab any members that registered to that group within the last month. Unfortunately, it instead continues to grab every member in the group, regardless of the time they joined.
Does anyone have any information into where I have went wrong?
Turns out, my version of Elgg was too low, otherwise that entire block of code would work. Working Elgg 1.8, I needed to use the following code:
$MemberDifference = elgg_get_entities_from_relationship_count(array(
'relationship' => 'member',
'relationship_guid' => $Reports->guid,
'inverse_relationship' => true,
'type' => 'user',
'limit' => 20,
'count' => true,
'joins' => array("JOIN {$db_prefix}users_entity u ON e.guid=u.guid"),
'order_by' => 'u.name ASC',
'wheres' => array('r.time_created >=' . $startTime)
));
This works perfectly and brings about exactly what im looking for.
I'm working on adding an additional column to an existing backend extension.
I'm determining the sells of the products to display their health of (roughly) the last 3 months.
If I implement this column the page takes upwards of a minute to be generated.
The code for the query I'm adding to the extension is:
$fromDate = date('Y-m-d H:i:s', strtotime('-90 days'));
$toDate = date('Y-m-d H:i:s', strtotime('-0 days'));
$collection->getSelect()->joinLeft(
array('order_items' => 'sales_flat_order_item'),
"`order_items`.`product_id` = `e`.`entity_id` AND
`order_items`.`created_at` BETWEEN '{$fromDate}' AND '{$toDate}'
AND `order_items`.`order_id` IN (SELECT entity_id FROM sales_flat_order
WHERE status = 'processing' OR status = 'complete' OR status = 'closed')
",
array('order_id', 'product_id')
);
$collection->getSelect()->columns('COUNT(order_items.order_id) AS stock_health');
$collection->getSelect()->group('e.entity_id');
The code for the column I'm adding is:
$stockManagerModel = Mage::getModel('stocklist/status');
$this->addColumn('stock_health', array(
'header' => 'Health', //Mage::helper('stocklist')->__('Health'),
'align' => 'right',
'filter' => false,
'width' => '60px',
'order_callback' => array($this, '_customSort'),
'renderer' => 'stocklist/adminhtml_widget_grid_column_renderer_health',
'index' => 'stock_health',
));
What is causing this extension to be so slow after this addition? What changes could/should be made? Is there a better way to implement this?
Just a bit doubt, are you checking your compilation process? Is it disabled or do you Run Compilation process once the module is enabled?
I am working on a project where we will be creating both subdomains as well as domains in Route53. We are hoping that there is a way to do this programmatically. The SDK for PHP documentation seems a little light, but it appears that createHostedZone can be used to create a domain or subdomain record and that changeResourceRecordSets can be used to create the DNS records necessary. Does anyone have examples of how to actually accomplish this?
Yes, this is possible using the changeResourceRecordSets call, as you already indicated. But it is a bit clumsy since you have to structure it like a batch even if you're changing/creating only one record, and even creations are changes. Here is a full example, without a credentials method:
<?php
// Include the SDK using the Composer autoloader
require 'vendor/autoload.php';
use Aws\Route53\Route53Client;
use Aws\Common\Credentials\Credentials;
$client = Route53Client::factory(array(
'credentials' => $credentials
));
$result = $client->changeResourceRecordSets(array(
// HostedZoneId is required
'HostedZoneId' => 'Z2ABCD1234EFGH',
// ChangeBatch is required
'ChangeBatch' => array(
'Comment' => 'string',
// Changes is required
'Changes' => array(
array(
// Action is required
'Action' => 'CREATE',
// ResourceRecordSet is required
'ResourceRecordSet' => array(
// Name is required
'Name' => 'myserver.mydomain.com.',
// Type is required
'Type' => 'A',
'TTL' => 600,
'ResourceRecords' => array(
array(
// Value is required
'Value' => '12.34.56.78',
),
),
),
),
),
),
));
The documentation of this method can be found here. You'll want to take very careful note of the required fields as well as the possible values for others. For instance, the name field must be a FQDN ending with a dot (.).
Also worth noting: You get no response back from the API after this call by default, i.e. there is no confirmation or transaction id. (Though it definitely gives errors back if something is wrong.) So that means that if you want your code to be bulletproof, you should write a Guzzle response handler AND you may want to wait a few seconds and then run a check that the new/changed record indeed exists.
Hope this helps!
Yes, I done using changeResourceRecordSets method.
<?php
require 'vendor/autoload.php';
use Aws\Route53\Route53Client;
use Aws\Exception\CredentialsException;
use Aws\Route53\Exception\Route53Exception;
//To build connection
try {
$client = Route53Client::factory(array(
'region' => 'string', //eg . us-east-1
'version' => 'date', // eg. latest or 2013-04-01
'credentials' => [
'key' => 'XXXXXXXXXXXXXXXXXXX', // eg. VSDFAJH6KXE7TXXXXXXXXXX
'secret' => 'XXXXXXXXXXXXXXXXXXXXXXX', //eg. XYZrnl/ejPEKyiME4dff45Pds54dfgr5XXXXXX
]
));
} catch (Exception $e) {
echo $e->getMessage();
}
/* Create sub domain */
try {
$dns = 'yourdomainname.com';
$HostedZoneId = 'XXXXXXXXXXXX'; // eg. A4Z9SD7DRE84I ( like 13 digit )
$name = 'test.yourdomainname.com.'; //eg. subdomain name you want to create
$ip = 'XX.XXXX.XX.XXX'; // aws domain Server ip address
$ttl = 300;
$recordType = 'CNAME';
$ResourceRecordsValue = array('Value' => $ip);
$client->changeResourceRecordSets([
'ChangeBatch' => [
'Changes' => [
[
'Action' => 'CREATE',
"ResourceRecordSet" => [
'Name' => $name,
'Type' => $recordType,
'TTL' => $ttl,
'ResourceRecords' => [
$ResourceRecordsValue
]
]
]
]
],
'HostedZoneId' => $HostedZoneId
]);
}
If you get any error please check into server error.log file. If you get error from SDK library then there is might PHP version not supported.
if you run this code from your local machine then you might get "SignatureDoesNotMatch" error then Make sure run this code into same (AWS)server environment.
I am using PHPExcel to generate some pretty hefty spreadsheets on the fly for our users. This seems to work fine until we start to get up to medium sized spreadsheets. I have user that is trying to export a spreadsheet that is about 6000 rows with 11 columns and this is bringing my script to its knees. Unfortunately because the spreadsheets are very dynamic there is no way to generate them ahead of time so I am stuck doing this on the fly for each user request.
I have run some tests and it seems that adding the rows to the spreadsheets gets continually slower as the script proceeds. For example the following is being reported by my error logging:
1st set of 1000 rows completes 13.34 Seconds into the script
2nd set of 1000 rows completes 54.57 Seconds into the script
3rd set of 1000 rows completes 135.33 Seconds into the script
4th set of 1000 rows completes 250.60 Seconds into the script
5th set of 1000 rows completes 394.53 Seconds into the script
I have adjusted the script to use the following code to add each row to the spreadsheet:
$sheet->fromArray($row_array, NULL, 'B' . $row_counter);
Instead of adding each cell individually, but have not seen any increase in speed.
The total code to create each row and format it is:
if($row_counter % 2 == 0){
$active_color = $even;}
Else{
$active_color = $odd;}
$sheet->getStyle('B' . $row_counter . ':' . chr($colspan_endletter) . $row_counter)->applyFromArray(
array('fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('argb' => $active_color)
),
'borders' => array(
'left' => array('style' => PHPExcel_Style_Border::BORDER_MEDIUM),
'right' => array('style' => PHPExcel_Style_Border::BORDER_MEDIUM)
)
)
);
$sheet
->getStyle('B' . $row_counter . ':' . chr($colspan_endletter) . $row_counter)
->getAlignment()
->setWrapText(true)
->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER)
->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
Any idea why this is killing my script, or a way to make it complete in a reasonable timeframe?
Well to start, your two calls to set the style could be combined into a single call:
$sheet->getStyle('B' . $row_counter . ':' . chr($colspan_endletter) . $row_counter)->applyFromArray(
array(
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('argb' => $active_color)
),
'borders' => array(
'left' => array('style' => PHPExcel_Style_Border::BORDER_MEDIUM),
'right' => array('style' => PHPExcel_Style_Border::BORDER_MEDIUM)
),
'alignment' => array(
'wrap' => true,
'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
'vertical' => PHPExcel_Style_Alignment::VERTICAL_CENTER
)
)
);
You could also set this as a default workbook style, and only set style for cells/ranges where it differed
Unfortunately, as your spreadsheets grow, PHPExcel will take longer and longer to generate them. If you think that 6.000 rows per spreadsheet is the maximum you will need to support, you can probably optimize your current code to make it faster.
However if you think you may have to generate bigger spreadsheets, you'll reach PHPExcel's limits and I would recommend you to look at other libraries that are built specifically for this use case, like Spout (https://github.com/box/spout). Your code will then be future-proof.
How can you specify a max result set for Magento SOAP queries?
I am querying Magento via SOAP API for a list of orders matching a given status. We have some remote hosts who are taking too long to return the list so I'd like to limit the result set however I don't see a parameter for this.
$orderListRaw = $proxy -> call ( $sessionId, 'sales_order.list', array ( array ( 'status' => array ( 'in' => $orderstatusarray ) ) ) );
I was able to see that we do get data back (6 minutes later) and have been able to deal with timeouts, etc. but would prefer to just force a max result set.
It doesn't seem like it can be done using limit, (plus you would have to do some complex pagination logic to get all records, because you would need know the total number of records and the api does not have a method for that) See api call list # http://www.magentocommerce.com/api/soap/sales/salesOrder/sales_order.list.html
But what you could do as a work around is use complex filters, to limit the result set base on creation date. (adjust to ever hour, day or week base on order volume).
Also, since you are using status type (assuming that you are excluding more that just cancel order), you may want to think about getting all order and keep track of the order_id/status locally (only process the ones with the above status) and the remainder that wasn't proceed would be a list of order id that may need your attention later on
Pseudo Code Example
$params = array(array(
'filter' => array(
array(
'key' => 'status',
'value' => array(
'key' => 'in',
'value' => $orderstatusarray,
),
),
),
'complex_filter' => array(
array(
'key' => 'created_at',
'value' => array(
'key' => 'gteq',
'value' => '2012-11-25 12:00:00'
),
),
array(
'key' => 'created_at',
'value' => array(
'key' => 'lteq',
'value' => '2012-11-26 11:59:59'
),
),
)
));
$orderListRaw = $proxy -> call ( $sessionId, 'sales_order.list', $params);
Read more about filtering # http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-8-varien-data-collections