Le nombre d'attributs dans le schéma de clé doit correspondre au nombre d'attributs définis dans les définitions d'attribut

107

J'essaie de créer une table simple en utilisant le shell javascript DynamoDB et j'obtiens cette exception:


    {   
    "message": "The number of attributes in key schema must match the number of attributes defined in attribute definitions.",
    "code": "ValidationException",
    "time": "2015-06-16T10:24:23.319Z",
    "statusCode": 400,
    "retryable": false 
    }

Voici le tableau que j'essaye de créer:


    var params = {
        TableName: 'table_name',
        KeySchema: [ 
            { 
                AttributeName: 'hash_key_attribute_name',
                KeyType: 'HASH',
            },

        ],
        AttributeDefinitions: [ 
            {
                AttributeName: 'hash_key_attribute_name',
                AttributeType: 'S', 
            },
            {
                AttributeName: 'attribute_name_1',
                AttributeType: 'S', 
            }
        ],
        ProvisionedThroughput: { 
            ReadCapacityUnits: 1, 
            WriteCapacityUnits: 1, 
        },


    };
    dynamodb.createTable(params, function(err, data) {
        if (err) print(err); 
        else print(data); 
    });

Cependant, si j'ajoute le deuxième attribut au keySchema, cela fonctionne bien. Ci-dessous une table de travail:


    var params = {
        TableName: 'table_name',
        KeySchema: [ 
            { 
                AttributeName: 'hash_key_attribute_name',
                KeyType: 'HASH',
            },
            { 
                AttributeName: 'attribute_name_1', 
                KeyType: 'RANGE', 
            }

        ],
        AttributeDefinitions: [ 
            {
                AttributeName: 'hash_key_attribute_name',
                AttributeType: 'S', 
            },
            {
                AttributeName: 'attribute_name_1',
                AttributeType: 'S', 
            }
        ],
        ProvisionedThroughput: { 
            ReadCapacityUnits: 1, 
            WriteCapacityUnits: 1, 
        },


    };
    dynamodb.createTable(params, function(err, data) {
        if (err) print(err); 
        else print(data); 
    });

Je ne veux pas ajouter la plage au schéma clé. Toute idée de comment résoudre ce problème?

NAbbas
la source
Cela se produit-il uniquement contre DynamoDBLocal? Que se passe-t-il lorsque vous essayez de faire la même chose contre le service réel?
mkobit
Je n'ai pas encore de compte AWS, je n'ai donc pas pu le tester par rapport au service réel. J'utilise la dernière version de DynamoDB local (dynamodb_local_2015-04-27_1.0).
NAbbas
1
Je rencontre le même comportement avec dynamodb_local_2016-04-19
Chris
2
Nevermind, TL de Mingliang; DR dit tout.
Chris

Réponses:

227

DynamoDB est sans schéma (sauf le schéma de clé)

En d'autres termes, vous devez spécifier le schéma de clé (nom et type d'attribut) lorsque vous créez la table. Eh bien, vous n'avez pas besoin de spécifier d'attributs non clés. Vous pouvez mettre un élément avec n'importe quel attribut plus tard (doit inclure les clés bien sûr).

À partir de la page de documentation , le AttributeDefinitionsest défini comme:

Un tableau d'attributs qui décrivent le schéma de clé pour la table et les index.

Lorsque vous créez une table, le AttributeDefinitionschamp est utilisé uniquement pour les clés de hachage et / ou de plage. Dans votre premier cas, il n'y a que la clé de hachage (numéro 1) tandis que vous fournissez 2 AttributeDefinitions. C'est la cause première de l'exception.

TL; DR N'incluez aucune définition d'attribut non clé dans AttributeDefinitions.

Mingliang Liu
la source
10
à une exception près, je crois, l'attribut non clé devrait être dans AttributeDefinitionssi cette clé sera utilisée comme clé hashou rangedans l'index
Srle
23

Lorsque vous utilisez un attribut non clé dans at "AttributeDefinitions", vous devez l'utiliser comme index, sinon cela va à l'encontre du fonctionnement de DynamoDB. Voir le lien .

Donc pas besoin de mettre un attribut non clé "AttributeDefinitions"si vous ne l'utilisez pas comme index ou clé primaire.

var params = {
        TableName: 'table_name',
        KeySchema: [ // The type of of schema.  Must start with a HASH type, with an optional second RANGE.
            { // Required HASH type attribute
                AttributeName: 'UserId',
                KeyType: 'HASH',
            },
            { // Optional RANGE key type for HASH + RANGE tables
                AttributeName: 'RemindTime', 
                KeyType: 'RANGE', 
            }
        ],
        AttributeDefinitions: [ // The names and types of all primary and index key attributes only
            {
                AttributeName: 'UserId',
                AttributeType: 'S', // (S | N | B) for string, number, binary
            },
            {
                AttributeName: 'RemindTime',
                AttributeType: 'S', // (S | N | B) for string, number, binary
            },
            {
                AttributeName: 'AlarmId',
                AttributeType: 'S', // (S | N | B) for string, number, binary
            },
            // ... more attributes ...
        ],
        ProvisionedThroughput: { // required provisioned throughput for the table
            ReadCapacityUnits: 1, 
            WriteCapacityUnits: 1, 
        },
        LocalSecondaryIndexes: [ // optional (list of LocalSecondaryIndex)
            { 
                IndexName: 'index_UserId_AlarmId',
                KeySchema: [ 
                    { // Required HASH type attribute - must match the table's HASH key attribute name
                        AttributeName: 'UserId',
                        KeyType: 'HASH',
                    },
                    { // alternate RANGE key attribute for the secondary index
                        AttributeName: 'AlarmId', 
                        KeyType: 'RANGE', 
                    }
                ],
                Projection: { // required
                    ProjectionType: 'ALL', // (ALL | KEYS_ONLY | INCLUDE)
                },
            },
            // ... more local secondary indexes ...
        ],
    };
    dynamodb.createTable(params, function(err, data) {
        if (err) ppJson(err); // an error occurred
        else ppJson(data); // successful response
    });
Gabriel Wu
la source
2

J'ai également eu ce problème et je posterai ici ce qui n'a pas fonctionné pour moi au cas où cela aiderait quelqu'un d'autre.

Dans mon CreateTableRequest, j'avais un tableau vide pour le GlobalSecondaryIndexes.

CreateTableRequest createTableRequest = new CreateTableRequest
{
  TableName = TableName,
  ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = 2, WriteCapacityUnits = 2 },
  KeySchema = new List<KeySchemaElement>
  {
     new KeySchemaElement
     {
        AttributeName = "Field1",
        KeyType = KeyType.HASH
     },
     new KeySchemaElement
     {
        AttributeName = "Field2",
        KeyType = KeyType.RANGE
     }
  },
  AttributeDefinitions = new List<AttributeDefinition>()
  {
     new AttributeDefinition
     {
         AttributeName = "Field1", 
         AttributeType = ScalarAttributeType.S
     },
     new AttributeDefinition
     {
        AttributeName = "Field2",
        AttributeType = ScalarAttributeType.S
     }
  },
  //GlobalSecondaryIndexes = new List<GlobalSecondaryIndex>
  //{                            
  //}
};

Commenter ces lignes dans la création de la table a résolu mon problème. Je suppose donc que la liste doit être null, pas vide.

NickBeaugié
la source