代码之家  ›  专栏  ›  技术社区  ›  Galathir Darkstone

DynamoDB+PHP使用aws-sdk给出itemGet()模式不匹配错误

  •  0
  • Galathir Darkstone  · 技术社区  · 1 年前

    首先,请允许我断言,我是这方面的一个相对的傻瓜,其余的都是自学成才的。

    我有一个名为“NeedsSystemData”的简单DynamoDB表,其中包括一个具有以下键/属性的记录:

    ResidentUUID (Partition key) = b4f1eda1-bf41-4a25-b86e-bb03c3c68099 (string)
    ResidentName (Sort key) = Galathir Darkstone (string)
    HUDKey = 704b24e5-3471-f67a-4395-9ab65a5a4031 (string)
    HUDurl = http://simhost-02134e0505318f492.agni.secondlife.io:12046/cap/6bcbd734-d6cd-c921-4cec-cd637e3c3613 (string)
    

    我有一个PHP脚本,其中包含以下代码:

    <?php
        // slcom.php
    
        // Prepping for DynamoDbClient
        require 'vendor/autoload.php';
        require 'credentials.php';
    
        use Aws\DynamoDb\DynamoDbClient;
        use Aws\DynamoDb\Exception\DynamoDbException;
        use Aws\DynamoDb\Marshaler;
    
        // Create a DynamoDBClient
        $client = new DynamoDbClient([
            'region' => $region,
            'version' => 'latest',
            'credentials' => [
                'key' => $access_key,
                'secret' => $secret_key,
            ],
        ]);
    
        // Global variable for table name
        $GLOBAL_TABLE_NAME = 'NeedsSystemData';
    
        try {
            $response = $client->scan([
                'TableName' => $GLOBAL_TABLE_NAME,
                'Limit' => 1, // Limit the scan to return only one item
            ]);
    
            $items = $response['Items'];
            if (!empty($items)) {
                $firstRecord = $items[0];
                echo 'First Record:' . PHP_EOL;
                echo 'ResidentUUID: ' . $firstRecord['ResidentUUID']['S'] . PHP_EOL;
                echo 'ResidentName: ' . $firstRecord['ResidentName']['S'] . PHP_EOL;
                echo 'HUDKey: ' . $firstRecord['HUDKey']['S'] . PHP_EOL;
                echo 'HUDurl: ' . $firstRecord['HUDurl']['S'] . PHP_EOL;
            } else {
                echo 'No records found in the table.' . PHP_EOL;
            }
        } catch (Exception $e) {
            echo 'Error: ' . $e->getMessage() . PHP_EOL;
        }
    
    ?>
    

    该代码生成以下输出:

    First Record: ResidentUUID: b4f1eda1-bf41-4a25-b86e-bb03c3c68099 ResidentName: Galathir Darkstone HUDKey: 704b24e5-3471-f67a-4395-9ab65a5a4031 HUDurl: http://simhost-02134e0505318f492.agni.secondlife.io:12046/cap/6bcbd734-d6cd-c921-4cec-cd637e3c3613
    

    到目前为止,一切都很好。然而,当我试图长期使用getItem()时,我会遇到一些问题。该代码是:

    <?php
        // slcom.php
    
        echo 'Opening Table' . PHP_EOL;
    
        // Prepping for DynamoDbClient
        require 'vendor/autoload.php';
        require 'credentials.php';
    
        use Aws\DynamoDb\DynamoDbClient;
        use Aws\DynamoDb\Exception\DynamoDbException;
        use Aws\DynamoDb\Marshaler;
    
        // Create a DynamoDBClient
        $client = new DynamoDbClient([
            'region' => $region,
            'version' => 'latest',
            'credentials' => [
                'key' => $access_key,
                'secret' => $secret_key,
            ],
        ]);
    
        // Global variable for table name
        $GLOBAL_TABLE_NAME = 'NeedsSystemData';
    
        try {
            // Use the specific ResidentUUID you want to retrieve
            $sampleResidentUUID = 'b4f1eda1-bf41-4a25-b86e-bb03c3c68099';
    
            $response = $client->getItem([
                'TableName' => $GLOBAL_TABLE_NAME,
                'Key' => [
                    'ResidentUUID' => ['S' => $sampleResidentUUID],
                ],
            ]);
    
            $item = $response['Item'];
            if (!empty($item)) {
                echo 'First Record:' . PHP_EOL;
                echo 'ResidentUUID: ' . $item['ResidentUUID']['S'] . PHP_EOL;
                echo 'ResidentName: ' . $item['ResidentName']['S'] . PHP_EOL;
                echo 'HUDKey: ' . $item['HUDKey']['S'] . PHP_EOL;
                echo 'HUDurl: ' . $item['HUDurl']['S'] . PHP_EOL;
            } else {
                echo 'No records found with the given ResidentUUID.' . PHP_EOL;
            }
        } catch (Exception $e) {
            echo 'Error: ' . $e->getMessage() . PHP_EOL;
        }
    ?>
    

    该代码的输出为:

    Opening Table Error: Error executing "GetItem" on "https://dynamodb.us-east-2.amazonaws.com"; AWS HTTP error: Client error: `POST https://dynamodb.us-east-2.amazonaws.com` resulted in a `400 Bad Request` response: {"__type":"com.amazon.coral.validate#ValidationException","message":"The provided key element does not match the schema" (truncated...) ValidationException (client): The provided key element does not match the schema - {"__type":"com.amazon.coral.validate#ValidationException","message":"The provided key element does not match the schema"}
    

    我有一种感觉,这是一件愚蠢而简单的事情,应该是显而易见的。。。除了上述的noobness。如果有人能帮我指明正确的方向,我将不胜感激。

    如果重要的话:脚本在运行Ubuntu 22.04.2 LTS(GNU/Linux 5.19.0-1028-aws x86_64)的aws EC2实例上以index.php的形式运行。

    1 回复  |  直到 1 年前
        1
  •  1
  •   Leeroy Hannigan    1 年前

    在DynamoDB中,GetItem必须始终包含主键。如果您只想获得分区键的项目,那么您可以使用 Query 方法,它可以返回仅与分区键匹配的所有项,在您的情况下,正如您所说,这将只是一个项。

        2
  •  0
  •   Galathir Darkstone    1 年前

    这个数字。当我再次审视整件事时,我发现了一个解决方案。由于我用Partition和Sort Key设置了表,所以我想我需要在getItem()查询中包含Sort Key,即使Partition Key总是唯一的。这个经过编辑的代码块解决了这个问题:

    try {
            // Use the specific ResidentUUID and ResidentName you want to retrieve
            $sampleResidentUUID = 'b4f1eda1-bf41-4a25-b86e-bb03c3c68099';
            $sampleResidentName = 'Galathir Darkstone';
    
            $response = $client->getItem([
                'TableName' => $GLOBAL_TABLE_NAME,
                'Key' => [
                    'ResidentUUID' => ['S' => $sampleResidentUUID],
                    'ResidentName' => ['S' => $sampleResidentName],
                ],
            ]);
    
            $item = $response['Item'];
            if (!empty($item)) {
                echo 'First Record:' . PHP_EOL;
                echo 'ResidentUUID: ' . $item['ResidentUUID']['S'] . PHP_EOL;
                echo 'ResidentName: ' . $item['ResidentName']['S'] . PHP_EOL;
                echo 'HUDKey: ' . $item['HUDKey']['S'] . PHP_EOL;
                echo 'HUDurl: ' . $item['HUDurl']['S'] . PHP_EOL;
            } else {
                echo 'No records found with the given ResidentUUID and ResidentName.' . PHP_EOL;
            }
        } catch (Exception $e) {
            echo 'Error: ' . $e->getMessage() . PHP_EOL;
        }
    

    我仍然很好奇,如果我用一个空的排序键设置表,我的原始代码是否有效?但我稍后会深入研究。

    快乐的编码。