键模式中的属性数量必须与属性定义中定义的属性数量相匹配
Number of attributes in key schema must match the number of attributes defined in attribute definitions
我正在尝试使用 DynamoDB JavaScript shell 创建一个简单的 table,但我遇到了这个异常:
{
"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
}
下面是我要创建的table:
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
,它就可以正常工作。下面是工作 table:
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);
});
我不想将范围添加到键架构。知道如何解决吗?
TL;DR 不要在 AttributeDefinitions
.
中包含任何非键属性定义
DynamoDB 是无模式的(键模式除外)
也就是说,您在创建table时需要指定密钥架构(属性名称和类型)。好吧,您不需要指定任何非键属性。您可以稍后放置具有任何属性的项目(当然必须包括密钥)。
从documentation page开始,AttributeDefinitions
定义为:
An array of attributes that describe the key schema for the table and indexes.
当您创建 table 时,AttributeDefinitions
字段仅用于散列 and/or 范围键。在您的第一种情况下,当您提供 2 个 AttributeDefinitions 时,只有哈希键(数字 1)。这是异常的根本原因。
我也遇到了这个问题,我会 post 在这里说明我出了什么问题,以防对其他人有所帮助。
在我的 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>
//{
//}
};
在 table 创建中注释掉这些行解决了我的问题。所以我猜列表必须是 null
,而不是空的。
在"AttributeDefinitions"
中使用非键属性时,必须将其作为索引使用,否则有悖于DynamoDB的工作方式。参见 the link。
因此,如果您不打算将其用作索引或主键,则无需将非键属性放入 "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
中声明属性
或
当这些属性将在 GlobalSecondaryIndexes
或 LocalSecondaryIndexes
中使用时
对于任何使用 yaml 文件的人:
示例 1:
假设您有 3 个属性 -> id、status、createdAt。
这里的id是KeySchema
AuctionsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: AuctionsTable
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
示例 2:
对于相同的属性(即 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
我们在 AttributeDefinitions 中包含 status 和 createdId 只是因为我们有一个使用上述属性的 GlobalSecondaryIndex
。
原因:DynamoDB只关心主键、GlobalSecondaryIndex和LocalSecondaryIndex。您不需要指定不属于上述三重奏的任何其他类型的属性。
DynamoDB只关心Primary Key,GlobalSecondaryIndex和LocalSecondaryIndex进行分区。它不关心您对某个项目有哪些其他属性。
不要在 --attribute-definitions
和 --key-schema
中包含所有键值。创建 table.
时仅在其中包含 HASH 和 RANGE 键
当你将一个项目插入 dynamo 时,它也会接受上面没有定义的其他键 attributes/schema。
例如:
正在创建 table:
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
现在您也可以插入包含其他键的项目,只需 id
和 sid
必须出现在项目中
我正在尝试使用 DynamoDB JavaScript shell 创建一个简单的 table,但我遇到了这个异常:
{
"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
}
下面是我要创建的table:
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
,它就可以正常工作。下面是工作 table:
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);
});
我不想将范围添加到键架构。知道如何解决吗?
TL;DR 不要在 AttributeDefinitions
.
DynamoDB 是无模式的(键模式除外)
也就是说,您在创建table时需要指定密钥架构(属性名称和类型)。好吧,您不需要指定任何非键属性。您可以稍后放置具有任何属性的项目(当然必须包括密钥)。
从documentation page开始,AttributeDefinitions
定义为:
An array of attributes that describe the key schema for the table and indexes.
当您创建 table 时,AttributeDefinitions
字段仅用于散列 and/or 范围键。在您的第一种情况下,当您提供 2 个 AttributeDefinitions 时,只有哈希键(数字 1)。这是异常的根本原因。
我也遇到了这个问题,我会 post 在这里说明我出了什么问题,以防对其他人有所帮助。
在我的 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>
//{
//}
};
在 table 创建中注释掉这些行解决了我的问题。所以我猜列表必须是 null
,而不是空的。
在"AttributeDefinitions"
中使用非键属性时,必须将其作为索引使用,否则有悖于DynamoDB的工作方式。参见 the link。
因此,如果您不打算将其用作索引或主键,则无需将非键属性放入 "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
中声明属性
或
当这些属性将在 GlobalSecondaryIndexes
或 LocalSecondaryIndexes
对于任何使用 yaml 文件的人:
示例 1:
假设您有 3 个属性 -> id、status、createdAt。
这里的id是KeySchema
AuctionsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: AuctionsTable
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
示例 2:
对于相同的属性(即 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
我们在 AttributeDefinitions 中包含 status 和 createdId 只是因为我们有一个使用上述属性的 GlobalSecondaryIndex
。
原因:DynamoDB只关心主键、GlobalSecondaryIndex和LocalSecondaryIndex。您不需要指定不属于上述三重奏的任何其他类型的属性。
DynamoDB只关心Primary Key,GlobalSecondaryIndex和LocalSecondaryIndex进行分区。它不关心您对某个项目有哪些其他属性。
不要在 --attribute-definitions
和 --key-schema
中包含所有键值。创建 table.
当你将一个项目插入 dynamo 时,它也会接受上面没有定义的其他键 attributes/schema。
例如:
正在创建 table:
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
现在您也可以插入包含其他键的项目,只需 id
和 sid
必须出现在项目中