0
votes

I'm new to AWS DynamoDB and to nosql in general, and I'm having problem with table creation.

I'm trying to create a table named User with the following Attributes:

  • UserId (HASH)
  • OSType (RANGE)
  • MSISDN
  • IMSI
  • DeviceID

I need to query the table not only by UserId, but also by the following fields:

  • MSISDN
  • IMSI
  • DeviceID

My Logic is as follows:

  1. Query the table by the UserId field.
  2. If the query returned no results create a new one, but check that there isn't other users with the same MSISDN filed OR the same IMSI field OR the same DeviceID field.

After reading the manual about LSI/GSI i'm having difficulties understating how to create the table and define those indexes.

This is the code i'm tring to execute to creater the table using PHP+AWS SDK:

    $client->createTable(array(
    'TableName' => 'User',
    'AttributeDefinitions' => array(
        array('AttributeName' => 'UserId',      'AttributeType' => 'S'),
        array('AttributeName' => 'OSType',      'AttributeType' => 'S'),
        array('AttributeName' => 'MSISDN',      'AttributeType' => 'S'),
        array('AttributeName' => 'IMSI',        'AttributeType' => 'S'),
        array('AttributeName' => 'DeviceID',    'AttributeType' => 'S'),
    ),
    'KeySchema' => array(
        array('AttributeName' => 'UserId', 'KeyType' => 'HASH'),
        array('AttributeName' => 'OSType', 'KeyType' => 'RANGE')
    ),
    'GlobalSecondaryIndexes' => array(
        array(
            'IndexName' => 'IMSIIndex',
            'KeySchema' => array(
                array('AttributeName' => 'IMSI',    'KeyType' => 'HASH')
            ),
            'Projection' => array(
                'ProjectionType' => 'KEYS_ONLY',
            ),
            'ProvisionedThroughput' => array(
                'ReadCapacityUnits'  => 10,
                'WriteCapacityUnits' => 10
            )
        ),
        array(
            'IndexName' => 'MSISDNIndex',
            'KeySchema' => array(
                array('AttributeName' => 'MSISDN',  'KeyType' => 'HASH')
            ),
            'Projection' => array(
                'ProjectionType' => 'KEYS_ONLY',
            ),
            'ProvisionedThroughput' => array(
                'ReadCapacityUnits'  => 10,
                'WriteCapacityUnits' => 10
            )
        ),
        array(
            'IndexName' => 'DeviceIDIndex',
            'KeySchema' => array(
                array('AttributeName' => 'DeviceID',    'KeyType' => 'HASH')
            ),
            'Projection' => array(
                'ProjectionType' => 'KEYS_ONLY',
            ),
            'ProvisionedThroughput' => array(
                'ReadCapacityUnits'  => 10,
                'WriteCapacityUnits' => 10
            )
        ),
    ),
    'ProvisionedThroughput' => array(
        'ReadCapacityUnits'  => 50,
        'WriteCapacityUnits' => 50
    )
));

I'm getting this error:

PHP Fatal error:  Uncaught Aws\DynamoDb\Exception\ValidationException: AWS Error Code: ValidationException, Status Code: 400, AWS Request ID: 70LGIARTTQF90S8P0HVRUKSJ27VV4KQNSO5AEMVJF66Q9ASUAAJG, AWS Error Type: client, AWS Error Message: One or more parameter values were invalid: Number of attributes in KeySchema does not exactly match number of attributes defined in AttributeDefinitions, User-Agent: aws-sdk-php2/2.4.11 Guzzle/3.7.4 curl/7.29.0 PHP/5.4.14

Please help me understand what am I doing wrong. I want to create the table with GSI, but I just can't comprehend the essence of secondary index in DynamoDB :(

2
I haven't used the PHP SDK but if you could use the AWS Console to create the table and set up the GSI just to get startedChen Harel
It looks like the PHP code is OK and the SDK is sending the data correctly to the service. The Aws\DynamoDb\Exception\ValidationException indicates that the service is rejecting your configuration. The error message from the service is a bit cryptic, but I think that the keys you are setting up in the GSIs are incorrect. You may also need a range key since your main table has a hash and range key. Try asking on the Amazon DynamoDB forumJeremy Lindblom
I had the same problem i solved by removing non-key attribute from AttributeDefinitions, and are you querying DynamoDB Local?Harshal Bulsara

2 Answers

1
votes

This should work:

$client->createTable(array(
'TableName' => 'User',
'AttributeDefinitions' => array(
    array('AttributeName' => 'UserId',      'AttributeType' => 'S'),
    array('AttributeName' => 'OSType',      'AttributeType' => 'S')
),
'KeySchema' => array(
    array('AttributeName' => 'UserId', 'KeyType' => 'HASH'),
    array('AttributeName' => 'OSType', 'KeyType' => 'RANGE')
),
'GlobalSecondaryIndexes' => array(
    array(
        'IndexName' => 'IMSIIndex',
        'KeySchema' => array(
            array('AttributeName' => 'IMSI',    'KeyType' => 'HASH')
        ),
        'Projection' => array(
            'ProjectionType' => 'KEYS_ONLY',
        ),
        'ProvisionedThroughput' => array(
            'ReadCapacityUnits'  => 10,
            'WriteCapacityUnits' => 10
        )
    ),
    array(
        'IndexName' => 'MSISDNIndex',
        'KeySchema' => array(
            array('AttributeName' => 'MSISDN',  'KeyType' => 'HASH')
        ),
        'Projection' => array(
            'ProjectionType' => 'KEYS_ONLY',
        ),
        'ProvisionedThroughput' => array(
            'ReadCapacityUnits'  => 10,
            'WriteCapacityUnits' => 10
        )
    ),
    array(
        'IndexName' => 'DeviceIDIndex',
        'KeySchema' => array(
            array('AttributeName' => 'DeviceID',    'KeyType' => 'HASH')
        ),
        'Projection' => array(
            'ProjectionType' => 'KEYS_ONLY',
        ),
        'ProvisionedThroughput' => array(
            'ReadCapacityUnits'  => 10,
            'WriteCapacityUnits' => 10
        )
    ),
),
'ProvisionedThroughput' => array(
    'ReadCapacityUnits'  => 50,
    'WriteCapacityUnits' => 50
)));

Hope that helps

4
votes

Only attributes that are included in local and global index should be defined in the AttributeDefinitions section.