键模式中的属性数必须与属性定义中定义的属性数匹配

我正在尝试使用 DynamoDB JavaScript shell 创建一个简单的表,但遇到了一个例外:

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

下面是我正在尝试创建的表:

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

然而,如果我将第二个属性添加到 KeySchema,它会工作得很好:

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

我不想将范围添加到键模式。有什么办法修复它吗?

96392 次浏览

不要在 AttributeDefinitions中包含任何非键属性定义。

DynamoDB 是无模式的(关键模式除外)

也就是说,在创建表时,确实需要指定键模式(属性名称和类型)。您不需要指定任何非键属性。您可以在以后放置具有任何属性的项(当然必须包括键)。

文件页来看,AttributeDefinitions的定义是:

描述表和索引的键架构的属性数组。

创建表时,AttributeDefinitions字段仅用于哈希和/或范围键。在第一种情况下,只有哈希键(数字1) ,而您提供了2个 AttributeDefinition。这是异常的根本原因。

我也有这个问题,我会在这里张贴我的错误,以防它帮助别人。

在我的 CreateTableRequest中,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>
//{
//}
};

在创建表时注释掉这些行解决了我的问题。所以我想列表必须是 null,而不是空的。

"AttributeDefinitions"中使用非键属性时,必须使用它作为索引,否则将违背 DynamoDB 的工作方式。见 链接

因此,如果不打算使用非键属性作为索引或主键,则不需要在 "AttributeDefinitions"中放置非键属性。

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

只有在使用 KeySchema中的属性时才在 AttrubuteDefinitions中声明属性

或者

当这些属性将在 GlobalSecondaryIndexesLocalSecondaryIndexes中使用时

对于任何使用 yaml 文件的人:

例子一:

假设您有3个属性-> id、 status、 createdAt。 这是 KeySchema

    AuctionsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: AuctionsTable
BillingMode: PAY_PER_REQUEST
        

AttributeDefinitions:
- AttributeName: id
AttributeType: S


KeySchema:
- AttributeName: id
KeyType: HASH

例子二:

对于相同的属性(即。Id,status 和 createdAt)如果你也有 GlobalSecondaryIndexes或者 LocalSecondaryIndexes,那么你的 yaml 文件看起来像:

AuctionsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: AuctionsTable-${self:provider.stage}
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: status
AttributeType: S
- AttributeName: endingAt
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
GlobalSecondaryIndexes:
- IndexName: statusAndEndDate
KeySchema:
- AttributeName: status
KeyType: HASH
- AttributeName: endingAt
KeyType: RANGE
Projection:
ProjectionType: ALL

我们在 AttributeDefinition 中包含 status 和 createdId 仅仅是因为我们有一个使用上述属性的 GlobalSecondaryIndex

原因: DynamoDB 只关心主键、 GlobalSecond daryIndex 和 LocalSecond daryIndex。您不需要指定任何其他类型的属性,这些属性不属于上面提到的三重奏的一部分。

DynamoDB 只关注用于分区的主键、 GlobalSecond daryIndex 和 LocalSecond daryIndex。它不关心你对一个项目有什么其他的属性。

不要包括 --attribute-definitions--key-schema中的所有键值。在创建表时只包含 HASH 和 RANGE 键。

当您将一个项目插入 Dynamo 时,它也会接受上面的属性/模式中没有定义的其他键。

例如:

创建表格:

aws dynamodb create-table \
--table-name Orders \
--attribute-definitions \
AttributeName=id,AttributeType=S \
AttributeName=sid,AttributeType=S \
--key-schema \
AttributeName=id,KeyType=HASH \
AttributeName=sid,KeyType=RANGE \
--provisioned-throughput \
ReadCapacityUnits=5,WriteCapacityUnits=5 \
--endpoint-url=http://localhost:4566

现在你可以插入一个项目包含其他键太,只是 idsid必须存在于该项目