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.