1

I have a PHP script, and in this script I have an associative array looks like this, so I have pairs of keys and values in the array:

$arr = array('First' => 'One', 'Second' => 'Two', 'Third' => 'Three');

I have a table in AWS DynamoDB, and on that table I have an attribute named details and its type is Map, which means it has a String Key and a String Value for every item in the Map, so eventually it looks like the associative array from the beginning of the question.

Now, what I want is to upload the associative array to the table at DynamoDB, to the details Map-type attribute.

On the DynamoDB PHP SDK Documentation, it is written that I need to upload the Map keys and values pairs manually, like this:

'M' => array(
    // Associative array of custom 'AttributeName' key names
    'AttributeName' => array(
        // Associative array of custom key value pairs
    ),
    // ... repeated
 ),

But, the problem is that I don't know how many pairs of keys and values are in the associative array, so I cannot split it to 2 arrays of keys and values and to upload it with the number of pairs I have:

$keys[0] => array('S' => $values[0]),
$keys[1] => array('S' => $values[1]),
...

Another option that I thought about was to create a loop, and each time to update the attribute in the DynamoDB table, but the problem is that it is a Map-type attribute, so I cannot use ADD or SET to update the map. I cannot also retrieve the exist map on the DB and add the new pair, because then I still stay with a Map-type variable.

I thought of another option, which is to split it to 2 arrays of keys and values and upload those arrays to the DB, but then I would lose the order of the strings in the arrays and the matching between the keys and the pairs, because DynamoDB orders the arrays alphabetically, so there is no match by the index number.

What can I do to upload the associative array to the DynamoDB table?

11
  • I'm not really sure what you need to do : is it to separate your keys and your values in 2 different arrays ? Commented Jul 21, 2017 at 8:32
  • No. What I need is to upload an associative array to DynamoDB, without losing the keys and values order, for example as a Map-type. What I wrote about seperating it into 2 different arrays is an idea I had, but I also wrote why it won't work. Commented Jul 21, 2017 at 8:34
  • Well this is hard to help, you need somebody who now DynamoDB sorry :( Or maybe with a simple version of your actual code with examples sets. Commented Jul 21, 2017 at 8:44
  • Even after reading the documentation I don't understand the problem. The documenation-pages I saw are these: 1) docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/… 2) docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/… Commented Jul 21, 2017 at 11:07
  • @David These are pages of S3 documentation, while my problem is related to DynamoDB. Commented Jul 21, 2017 at 11:17

2 Answers 2

3

You can use DynamoDB Marshaler! Class. The Marshaler object has methods for marshaling JSON documents and PHP arrays to the DynamoDB item format and unmarshaling them back.

    $data = [
    'id' => '5432c69300594',
    'name' => [
        'first'  => 'Jeremy',
        'middle' => 'C',
        'last'   => 'Lindblom',
    ],
    'age' => 30,
    'phone_numbers' => [
        [
            'type'      => 'mobile',
            'number'    => '5555555555',
            'preferred' => true
        ],
        [
            'type'      => 'home',
            'number'    => '5555555556',
            'preferred' => false
        ],
    ],
];

// Marshaling the data and putting an item.
$client->putItem([
    'TableName' => 'YourTable',
    'Item'      => $marshaler->marshalItem($data)
]);

// Getting and item and unmarshaling the data.
$result = $client->getItem([
    'TableName' => 'YourTable',
    'Key'       => ['id' => ['S' => '5432c69300594']]
]);
$data = $marshaler->unmarshalItem($result['Item']);

Here is the reference: https://aws.amazon.com/es/blogs/developer/dynamodb-json-and-array-marshaling-for-php/

Sign up to request clarification or add additional context in comments.

Comments

2
+50

If I understand your question correctly, I think you basically have what you need. You seem to have mistakenly interpreted AttributeName as a literal string rather than the placeholder for the name that you've defined ('details'). I did the same thing myself the first time through.

According to the docs for PutItem, the 'Item' attribute in your API call should look like this.

'Item' => array(
    'details'  => array(
        'M' => array(
            'First' => array( 'S' => 'One'),
            'Second' => array( 'S' => 'Two'),
            'Third' => array( 'S' => 'Three'),
        ),
    ),
), etc.

So if you take your original $arr and using a loop or array_map() create a new array $arr2 in that format, you can just assign it:

'Item' => array(
    'details'  => array( 'M' => $arr2 ),
),

Same would apply for UpdateItem

'ExpressionAttributeNames' => array(
  '#d' => 'details'
),
'ExpressionAttributeValues' => array(
  ':d' => array(
    'M' => array(
      'First' => array( 'S' => 'One'),
      'Second' => array( 'S' => 'Two'),
      'Third' => array( 'S' => 'Three')
    )
  )
),
'UpdateExpression' => 'SET #d = :d',

1 Comment

If you use UpdateItem, you'll have to use 'ExpressionAttributeNames' and 'ExpressionAttributeValues' to define the key and map values, while setting the "UpdateExpression". See Edit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.