веб-сервисы Amazon — проблема AWS PHP SDK с Dynamodb WriteRequestBatch

Я экспериментирую с WriteRequestBatch из AWS SDK для Dynamodb. Ниже мой код. Все работает, кроме части WriteRequestBatch. Я понятия не имею, почему, и мне было интересно, может ли сообщество помочь мне здесь. Что я могу делать не так? Я попробовал поискать и поискать здесь, и нашел только 8 других вопросов, которые могли быть связаны, но, к сожалению, не помогли.

это это то, откуда я начал

$ddb_client = DynamoDbClient::factory(array(
'region' => 'us-east-1',
'key' => 'my_key',
'secret' => 'my_secret'
));

$ddb_client->createTable(array(
'TableName' => 'my_table',
'AttributeDefinitions' => array(
array(
'AttributeName' => 'id',
'AttributeType' => 'S'
),
array(
'AttributeName' => 'ns',
'AttributeType' => 'S'
)
),
'KeySchema' => array(
array(
'AttributeName' => 'id',
'KeyType'       => 'HASH'
),
array(
'AttributeName' => 'ns',
'KeyType'       => 'RANGE'
)
),
'ProvisionedThroughput' => array(
'ReadCapacityUnits'  => 10,
'WriteCapacityUnits' => 10
)
));

$response = $ddb_client->putItem(array(
"TableName" => "my_table",
"Item" => array(
"id" => array("S" => "exp_id"),
"ns" => array("S" => "exp_ns"),
"version" => array("N" => "0"),
),
));

$item = $response['Item'];
$item['version']['N'] = '1';

$put_batch = WriteRequestBatch::factory($ddb_client);
$put_request = new PutRequest(
array(
"Item" => $item,
"Expected" => array(
"version" => array(
"ComparisonOperator" => "EQ",
"AttributeValueList" => array(
array("N" => "0")
)
),
),
),
"my_table");
$putBatch->add($put_request);
$putBatch->flush();

Это работает вместо WriteRequestBatch. Мне просто нужно управлять партиями, чтобы поставить себя, чем использовать WriteRequestBatch, делая это для меня:

$response = $ddb_client->batchWriteItem(array(
"RequestItems" => array(
"my_table" => array(
array(
"PutRequest" => array(
"Item" => $item,
"Expected" => array(
"version" => array(
"ComparisonOperator" => "EQ",
"AttributeValueList" => array(
array("S" => "0")
)
),
),
)
)
)
)
));

1

Решение

ответ от Geek Stocks неполно, но все же полезно. Одна вещь, которую вы можете сделать, обрабатывать асинхронные аспекты CreateTable операция заключается в использовании Официант:

$ddb_client->createTable(array('TableName' => 'my_table', ... ));
$ddb_client->waitUntil('TableExists', array('TableName' => 'my_table'));

тем не мение, Существует также проблема с тем, как вы используете WriteRequestBatch учебный класс. Когда вы создаете PutRequest, вы должны передать элемент, а не целый набор PutItem параметры. WriteRequestBatch это абстракция над DynamoDB BatchWriteItem операция, который не позволяет такие вещи, как Expected параметр. Если вы хотите сделать это, то вам нужно использовать индивидуальные PutItem/UpdateItem/DeleteItem Запросы.

Вот измененная версия вашего использования WriteRequestBatch это правильно:

$putBatch = WriteRequestBatch::factory($ddb_client);
$putBatch->add(new PutRequest($item, 'my_table'));
// ADD MORE...
// ...
// ...
$putBatch->flush();

Вот еще один пример использования WriteRequestBatch из руководства пользователя SDK.


РЕДАКТИРОВАТЬ: Еще один полный пример, который работает, который я только что протестировал, который показывает разницу между версиями до 2.7.0 и позже

use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Model\BatchRequest\WriteRequestBatch;
use Aws\DynamoDb\Model\BatchRequest\PutRequest;
use Aws\DynamoDb\Model\Item;

$client = DynamoDbClient::factory([/* ... */]);
$batch = WriteRequestBatch::factory($client);
for ($i = 1; $i <= 55; $i++) {
// FOR ANY SDK VERSION
// (NOTE: Does not support new M, L, BOOL, and NULL types)
$item = Item::fromArray(['id' => $i, 'data' => "foo{$i}"]);
// FOR SDK >= 2.7
$item = ['id' => ['N' => $i], 'data' => ['S' => "foo{$i}"]];

$batch->add(new PutRequest($item, 'my-table'));
}
$batch->flush();
0

Другие решения

Поскольку в настоящее время у вас нет обработки ошибок типа «попробуй / поймай» вокруг своего кода, вы, вероятно, не получите достоверную информацию о своей ошибке.

Я поместил блоки try / catch в ваш код и обнаружил, что таблица создается просто отлично, но вызов putItem завершается неудачно по следующей причине: Запрашиваемый ресурс не найден

Когда вы создаете таблицу, она НЕ доступна сразу. Вы должны сделать паузу, пока она не станет доступной. Этот параграф документов AWS объясняет это красиво:

CreateTable — асинхронная операция. Получив запрос CreateTable, DynamoDB немедленно возвращает ответ с TableStatus CREATING. После создания таблицы DynamoDB устанавливает для TableStatus значение ACTIVE. Вы можете выполнять операции чтения и записи только в таблице ACTIVE. Вы можете использовать API DescribeTable для проверки статуса таблицы.

Как только вы добавите вызов в DescribeTable, как он показывает, у вас все получится.

0