0

First, allow me to predicate that I am a relative noob to much of this, and self-taught in the rest.

I have a simple DynamoDB table set up named 'NeedsSystemData' that includes one record with the following Keys/Attributes:

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)

I have one PHP script with this code:

<?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;
    }

?>

That code generates this output:

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

So far, so good. However, when I try to move long to using a getItem(), I have some problems. That code is:

<?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;
    }
?>

The output from that code is:

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"}

I have a feeling this is something stupidly simple that should be obvious... except for the afore-mentioned noobness. If someone less noob would help point me in the right direction, I would appreciate it.

In case it matters: The scripts are being run as index.php on an aws EC2 instance running Ubuntu 22.04.2 LTS (GNU/Linux 5.19.0-1028-aws x86_64).

1

2 Answers 2

1

In DynamoDB a GetItem must always include the primary key. If you would like to get an item with just the partition key, then you can use the Query method, which can return all the items that match just the partition key, in your case as you stated that would just be a single item.

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

Comments

0

Well that figures. As soon as I took another look at the whole thing I found a resolution. Since I set up the Table with both a Partition and Sort Key, I guess I needed to include the Sort Key in getItem() query, even though the Partition Key is always going to be unique. This edited code block resolved it:

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;
    }

I am still curious if my original code had worked if I had set up the table with an empty sort key? But I'll dig into that later.

Happy coding.

Comments

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.