Die Anzahl der Attribute im Schlüsselschema muss mit der Anzahl der in den Attributdefinitionen definierten Attribute übereinstimmen

106

Ich versuche, eine einfache Tabelle mit der DynamoDB-Javascript-Shell zu erstellen, und erhalte die folgende Ausnahme:


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

Unten ist die Tabelle, die ich erstellen möchte:


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

Wenn ich jedoch das zweite Attribut zum keySchema hinzufüge, funktioniert es einwandfrei. Unterhalb des Arbeitstisches:


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

Ich möchte den Bereich nicht zum Schlüsselschema hinzufügen. Irgendeine Idee, wie man das behebt?

NAbbas
quelle
Geschieht dies nur gegen DynamoDBLocal? Was passiert, wenn Sie versuchen, dasselbe gegen den tatsächlichen Dienst zu tun?
mkobit
Ich habe noch kein AWS-Konto und konnte es daher nicht mit dem tatsächlichen Service testen. Ich verwende die neueste Version von DynamoDB local (dynamodb_local_2015-04-27_1.0).
NAbbas
1
Ich habe das gleiche Verhalten mit dynamodb_local_2016-04-19
Chris
2
Vergiss nicht, Mingliangs TL; DR sagt alles.
Chris

Antworten:

226

DynamoDB ist schemenlos (mit Ausnahme des Schlüsselschemas)

Das heißt, Sie müssen das Schlüsselschema (Attributname und -typ) angeben, wenn Sie die Tabelle erstellen. Nun, Sie müssen keine Nicht-Schlüsselattribute angeben. Sie können später ein Element mit einem beliebigen Attribut einfügen (muss natürlich die Schlüssel enthalten).

Von der Dokumentationsseite , die AttributeDefinitionsdefiniert ist als:

Ein Array von Attributen, die das Schlüsselschema für die Tabelle und die Indizes beschreiben.

Wenn Sie eine Tabelle erstellen, wird das AttributeDefinitionsFeld nur für die Hash- und / oder Bereichsschlüssel verwendet. In Ihrem ersten Fall gibt es nur einen Hash-Schlüssel (Nummer 1), während Sie 2 AttributeDefinitions angeben. Dies ist die Hauptursache für die Ausnahme.

TL; DR Fügen Sie keine Nicht-Schlüsselattributdefinitionen in ein AttributeDefinitions.

Mingliang Liu
quelle
10
Mit einer Ausnahme, glaube ich, sollte Nicht-Schlüssel-Attribut in sein, AttributeDefinitionswenn dieser Schlüssel als hashoder rangeSchlüssel im Index verwendet wird
Srle
22

Wenn Sie in at ein Nicht-Schlüsselattribut verwenden "AttributeDefinitions", müssen Sie es als Index verwenden, da dies sonst die Funktionsweise von DynamoDB beeinträchtigt. Siehe den Link .

Sie müssen also kein Nichtschlüsselattribut eingeben, "AttributeDefinitions"wenn Sie es nicht als Index oder Primärschlüssel verwenden möchten.

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
quelle
2

Ich hatte auch dieses Problem und ich werde hier posten, was für mich schief gelaufen ist, falls es jemand anderem hilft.

In meinem CreateTableRequesthatte ich ein leeres Array für die 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>
  //{                            
  //}
};

Das Auskommentieren dieser Zeilen in der Tabellenerstellung löste mein Problem. Ich denke, die Liste muss nullnicht leer sein.

NickBeaugié
quelle