2014-12-05 2 views
1

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

This, откуда я начал.

$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") 
          ) 
         ), 
        ), 
       ) 
      ) 
     ) 
    ) 
)); 

ответ

0

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

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

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

Вот модифицированная версия вашего использования WriteRequestBatch, что является правильным:

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

Here is another example of using the WriteRequestBatch from the SDK's User Guide.


EDIT: Еще один полный пример, который работает, что я просто проверял, что показывает разницу между версиями до 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

На самом деле Джереми, код в документах, на которые вы ссылаетесь, довольно сломан. Попробуйте прямое копирование/вставку, и вы поймете, что я имею в виду. Броски "Аргумент 1 передан Aws \ DynamoDb \ Model \ BatchRequest \ PutRequest :: __ construct() должен быть экземпляром Aws \ DynamoDb \ Model \ Item, array given ... « Возможно, API впереди документов? Хммм ... все еще работаю над этим. –

+0

Да, это сломано – bagi

+0

@Jeremy Я не знаю, заметили ли вы ** [Это] (http://docs.aws.amazon.com/aws-sdk-php/guide/latest/service-dynamodb.html# using-the-writerequestbatch), откуда я начал. **, Это указывает на ссылку AWS SDK. – bagi

0

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

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

При создании таблицы это НЕ сразу доступно. Вы должны сделать паузу, пока она не станет доступной. This paragraph of the AWS docs объясняет это красиво:

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

Как только вы добавляете вызов DescribeTable, как показано на рисунке, вы должны быть хорошими.

+0

Я не знаю, если вы заметили это, но ** Все работает, кроме части WriteRequestBatch **. Я действительно пытаюсь захватить блок вокруг части WriteRequestBatch в моем фактическом коде. Этот код является упрощенным примером, который я создал на основе моего фактического кода, который страдает от той же проблемы. – bagi

+0

@bagi Много раз OP думает, что у них есть проблема в одной части их кода, когда на самом деле это то, чего они еще не видят. Нет, я не заметил, потому что код, который вы опубликовали, хорошо прорывается перед частью WriteRequestBatch. Кроме того, ваш код выглядел правильно в соответствии с документацией. –

+0

Я бы сказал об этом. Извините, что :) – bagi

Смежные вопросы