Jumlah atribut dalam skema kunci harus sesuai dengan jumlah atribut yang ditentukan dalam definisi atribut

109

Saya mencoba membuat tabel sederhana menggunakan shell javascript DynamoDB dan saya mendapatkan pengecualian ini:


    {   
    "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 bawah ini adalah tabel yang saya coba buat:


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

Namun jika saya menambahkan atribut kedua ke keySchema, itu berfungsi dengan baik. Di bawah meja kerja:


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

Saya tidak ingin menambahkan rentang ke skema kunci. Tahu bagaimana cara memperbaikinya?

NAbbas
sumber
Apakah ini hanya terjadi terhadap DynamoDBLocal? Apa yang terjadi jika Anda mencoba melakukan hal yang sama terhadap layanan sebenarnya?
mkobit
Saya belum memiliki akun AWS, jadi tidak dapat mengujinya dengan layanan sebenarnya. Saya menggunakan versi terbaru DynamoDB local (dynamodb_local_2015-04-27_1.0).
NAbbas
1
Saya mengalami perilaku yang sama dengan dynamodb_local_2016-04-19
Chris
2
Tidak masalah, TL; DR Mingliang mengatakan itu semua.
Chris

Jawaban:

230

DynamoDB tidak memiliki skema (kecuali skema kunci)

Artinya, Anda perlu menentukan skema kunci (nama dan jenis atribut) saat Anda membuat tabel. Nah, Anda tidak perlu menentukan atribut non-kunci apa pun. Anda bisa meletakkan item dengan atribut apapun nanti (harus menyertakan kunci tentunya).

Dari halaman dokumentasi , AttributeDefinitionsdidefinisikan sebagai:

Larik atribut yang mendeskripsikan skema kunci untuk tabel dan indeks.

Saat Anda membuat tabel, AttributeDefinitionsbidang hanya digunakan untuk hash dan / atau kunci rentang. Dalam kasus pertama Anda, hanya ada kunci hash (nomor 1) saat Anda memberikan 2 AttributeDefinitions. Ini adalah akar penyebab pengecualian.

TL; DR Jangan menyertakan definisi atribut non-kunci apa pun dalam AttributeDefinitions.

Mingliang Liu
sumber
10
dengan satu pengecualian saya percaya, atribut non-kunci harus ada AttributeDefinitionsjika kunci itu akan digunakan sebagai hashatau rangekunci dalam indeks
Srle
23

Saat Anda menggunakan atribut non-key di di "AttributeDefinitions", Anda harus menggunakannya sebagai indeks, jika tidak, ini bertentangan dengan cara kerja DynamoDB. Lihat linknya .

Jadi tidak perlu memasukkan atribut non-key "AttributeDefinitions"jika Anda tidak akan menggunakannya sebagai indeks atau kunci utama.

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

Saya juga mengalami masalah ini dan saya akan memposting di sini apa yang salah untuk saya seandainya itu membantu orang lain.

Di saya CreateTableRequest, saya memiliki array kosong untuk 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>
  //{                            
  //}
};

Mengomentari baris-baris ini dalam pembuatan tabel memecahkan masalah saya. Jadi saya rasa daftarnya harus null, tidak kosong.

NickBeaugié
sumber