web-dev-qa-db-fra.com

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

J'essaie de créer un tableau simple à l'aide du 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 je tente 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 souhaite pas ajouter la plage au schéma de clé. Toute idée de comment résoudre ce problème?

77
NAbbas

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

Cela signifie que vous devez spécifier le schéma de clé (nom et type d'attribut) lors de la création de la table. Eh bien, vous n'avez pas besoin de spécifier d'attributs non clés. Vous pouvez placer un élément avec n'importe quel attribut ultérieurement (vous devez inclure les clés du cours).

À partir de la page de documentation , le AttributeDefinitions est défini comme suit:

Tableau d'attributs décrivant le schéma de clé de la table et des index.

Lorsque vous créez une table, le champ AttributeDefinitions 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) pendant 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.

172
Mingliang Liu

Lorsque vous utilisez un attribut non-clé dans l'attribut "AttributeDefinitions", vous devez l'utiliser comme index, sinon, cela va à l'encontre de la façon dont dynamodb fonctionne. voir lien

Donc pas besoin de mettre l'attribut non-clé dans "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

    });
15
Gabriel Wu

J'ai également eu ce problème et je posterai ici ce qui ne va pas au cas où cela aiderait quelqu'un d'autre.

Dans mon CreateTableRequest, j'avais un tableau vide pour les 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 table a résolu mon problème. Donc, je suppose que la liste doit être nulle, pas vide.

1
NickBeaugié