WriteRequestBatch with PHP AWS SDK 3 for DynamoDB
Most of the examples for WriteRequestBatch refer to an outdated version of the AWS SDK for PHP and apart from a Github thread, I was surprised to find so little information online.
The WriteRequestBatch class is very useful: it completely auto-manage a BatchWriteItem queue and it’s super convenient if you have — like me — to migrate several millions of rows. If you reach your Write Capacity, the class will wait until you can write again. I mean it’s not rocket science and you could write your own code, but why bother when it’s already part of the official SDK?
My first problem was that I had an error in my syntax but wasn’t able to debug with try/catch because, as the documentation explains, you need to pass the error-handling function as a parameter to the configuration object.
$config = [
'table' => $tableName,
'error' => function($e) { if ($e instanceof Exception) { echo $e->getMessage(); } })
];
$putBatch = new WriteRequestBatch($client,$config);
Apart from the error-handling function you can also set a default table for the operations, which I recommend so that you don’t need to send it with each request.
What changed the most from the previous version, however, is how you pass each put request. The syntax goes from this to the code below.
$data = [
'id' => $itemId,
'timestamp' => time(),
];
$putBatch->put($marshaler->marshalJson($data));
If you’re not using Marshaler, you can use a simple array with types (I am using the example of the official AWS documentation).
$data = [
'id' => ['S' => $itemId],
'timestamp' => ['N' => (string) time()],
];
$putBatch->put($data);
Beware that differently from the previous version, each item you put is just the data array, not a PutRequest!
Hope this was useful to save you few minutes with a proper example.
Full example below
$tableName = 'batch-write-test'; // This table has a HashKey named "id"$config = [
'table' => $tableName,
'error' => function($e) { if ($e instanceof Exception) { echo $e->getMessage(); } })
];
$putBatch = new WriteRequestBatch($client,$config);for ($i = 0; $i < 55; $i++) {
$itemId = uniqid();
$data = [
'id' => $itemId,
'timestamp' => time(),
];
$putBatch->put($marshaler->marshalJson($data));
}