Il numero di attributi nello schema chiave deve corrispondere al numero di attributi definiti nelle definizioni degli attributi


107

Sto cercando di creare una semplice tabella utilizzando la shell javascript DynamoDB e ricevo questa eccezione:


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

Di seguito è la tabella che sto cercando di creare:


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

Tuttavia, se aggiungo il secondo attributo a keySchema, funziona bene. Di seguito il tavolo di lavoro:


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

Non voglio aggiungere l'intervallo allo schema chiave. hai qualche idea su come aggiustarlo?


Succede solo contro DynamoDBLocal? Cosa succede quando provi a fare la stessa cosa contro il servizio effettivo?
— mkobit

Non ho ancora un account AWS, quindi non ho potuto testarlo rispetto al servizio effettivo. Sto usando l'ultima versione di DynamoDB local (dynamodb_local_2015-04-27_1.0).
— NAbbas

1
Sto riscontrando lo stesso comportamento con dynamodb_local_2016-04-19
— Chris

2
Non importa, TL di Mingliang; DR dice tutto.
— Chris

Risposte:


227

DynamoDB è privo di schemi (tranne lo schema della chiave)

Vale a dire, è necessario specificare lo schema della chiave (nome e tipo di attributo) quando si crea la tabella. Bene, non è necessario specificare alcun attributo non chiave. Puoi inserire un articolo con qualsiasi attributo in un secondo momento (deve includere le chiavi ovviamente).

Dalla pagina della documentazione , AttributeDefinitionssi definisce:

Un array di attributi che descrivono lo schema delle chiavi per la tabella e gli indici.

Quando crei una tabella, il AttributeDefinitionscampo viene utilizzato solo per le chiavi hash e / o intervallo. Nel tuo primo caso, c'è solo la chiave hash (numero 1) mentre fornisci 2 AttributeDefinitions. Questa è la causa principale dell'eccezione.

TL; DR Non includere definizioni di attributi non chiave in AttributeDefinitions.


10
con un'eccezione credo, l'attributo non chiave dovrebbe essere presente AttributeDefinitionsse quella chiave verrà utilizzata come hasho rangechiave nell'indice
— Srle

23

Quando usi un attributo non chiave in at "AttributeDefinitions", devi usarlo come indice, altrimenti è contro il modo in cui DynamoDB funziona. Vedi il link .

Quindi non è necessario inserire un attributo non chiave "AttributeDefinitions"se non lo si intende utilizzare come indice o chiave primaria.

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

2

Ho anche avuto questo problema e posterò qui cosa è andato storto nel caso in cui aiuti qualcun altro.

Nel mio CreateTableRequest, avevo un array vuoto per il file 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>
  //{                            
  //}
};

Commentare queste righe nella creazione della tabella ha risolto il mio problema. Quindi immagino che l'elenco debba essere null, non vuoto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.