【问题标题】:Upload an Associative Array to DynamoDB using PHP使用 PHP 将关联数组上传到 DynamoDB
【发布时间】:2017-12-14 16:20:48
【问题描述】:

我有一个 PHP 脚本,在这个脚本中我有一个关联数组,看起来像这样,所以我在数组中有一对键和值:

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

我在 AWS DynamoDB 中有一个表,在该表上我有一个名为 details 的属性,它的类型是 Map,这意味着它有一个 String 键和一个 String 值用于Map,所以最终它看​​起来像问题开头的关联数组。

现在,我想要将关联数组上传到 DynamoDB 的表中,到 details Map-type 属性。

在 DynamoDB PHP SDK 文档中,写到我需要手动上传 Map 键和值对,如下所示:

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

但是,问题是我不知道关联数组中有多少对键和值,所以我不能将它拆分为 2 个键和值数组并用我拥有的对数上传它:

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

我想到的另一个选项是创建一个循环,每次更新DynamoDB表中的属性,但问题是它是一个Map类型的属性,所以我不能使用ADD或@987654333 @更新地图。我也无法检索数据库上的现有地图并添加新对,因为那时我仍然使用地图类型的变量。

我想到了另一种选择,将其拆分为 2 个键和值数组并将这些数组上传到数据库,但这样我会丢失数组中字符串的顺序以及键和值之间的匹配对,因为 DynamoDB 按字母顺序排列数组,所以没有按索引号匹配。

如何将关联数组上传到 DynamoDB 表?

【问题讨论】:

  • 我不太确定您需要做什么:是将您的键和您的值分隔在 2 个不同的数组中吗?
  • 没有。我需要的是在不丢失键和值顺序的情况下将关联数组上传到 DynamoDB,例如作为 Map 类型。我写的关于将它分成 2 个不同的数组是我的一个想法,但我也写了为什么它不起作用。
  • 嗯,这很难提供帮助,你需要一个现在 DynamoDB 抱歉的人 :( 或者也许使用带有示例集的实际代码的简单版本。
  • 即使在阅读了文档之后我也不明白问题所在。我看到的文档页面是:1)docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/… 2)docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/…
  • @David 这些是 S3 文档页面,而我的问题与 DynamoDB 有关。

标签: php arrays string dictionary amazon-dynamodb


【解决方案1】:

您可以使用DynamoDB Marshaler!班级。 Marshaler 对象具有将 JSON 文档和 PHP 数组编组为 DynamoDB 项目格式并将它们解组回来的方法。

    $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']);

这是参考:https://aws.amazon.com/es/blogs/developer/dynamodb-json-and-array-marshaling-for-php/

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,我认为您基本上拥有所需的东西。您似乎错误地将 AttributeName 解释为文字字符串,而不是您定义的名称的占位符(“详细信息”)。 第一次我自己也做了同样的事情。

    根据docs for PutItem,API 调用中的“Item”属性应如下所示。

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

    因此,如果您使用原始 $arr 并使用循环或 array_map() 以该格式创建一个新数组 $arr2,则可以分配它:

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

    同样适用于 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',
    

    【讨论】:

    • 如果您使用 UpdateItem,则必须使用 'ExpressionAttributeNames' 和 'ExpressionAttributeValues' 来定义键和映射值,同时设置“UpdateExpression”。请参阅编辑。
    猜你喜欢
    • 2012-09-12
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2010-09-11
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    相关资源
    最近更新 更多