I am just doing a simple task in DynamoDB:
我只是做了一个简单的任务:
- Create a Table,
- 创建一个表,
- Add an Item to it
- 向它添加一个项。
- Query the Table for that Item.
- 查询该项目的表。
Here's a script that I am using:
下面是我使用的一个脚本:
from boto.dynamodb2.fields import HashKey, RangeKey, AllIndex, GlobalAllIndex
from boto.dynamodb2.items import Item
from boto.dynamodb2.layer1 import DynamoDBConnection
from boto.dynamodb2.table import Table
# Using DynamoDB Local
conn = DynamoDBConnection(host='localhost', port=8000, is_secure=False)
## ----- Create a table -----
throughput = {
'write': 1,
'read': 1
}
schema = [
HashKey('id'),
RangeKey('rating')
]
local_indexes = [
AllIndex('local_all_index_seats', parts=[
HashKey('id'),
RangeKey('seats')
])
]
global_indexes = [
GlobalAllIndex('global_all_index_color', parts=[
HashKey('color'),
RangeKey('rating')
])
]
new_table = Table.create('items', schema=schema, indexes=local_indexes,
global_indexes=global_indexes, connection=conn,
throughput=throughput)
print 'Table created'
## -------- Table created ---------
## -------- Add an item --------
items_table = Table('items', connection=conn) # New reference to the table we created
new_item_data = {
"category": "Sofa",
"rating": "4",
"color": "beige",
"seats": "6",
"id": "first_id"
}
new_item = Item(items_table, new_item_data)
new_item.save()
print 'New item saved'
## -------- Item added --------
## -------- Query Item --------
items_table = Table('items', connection=conn) # New reference to the table we created
queried_item = items_table.get_item(id='first_id')
print 'Query done. Category is: {}'.format(queried_item['Category'])
## -------- Querying Done --------
When I run this script, I get a ValidationException
:
当我运行这个脚本时,我得到一个ValidationException:
(backend)aniket [~/PycharmProjects/website_backend] -> python reproduce.py ±[●●][master]
Table created
New item saved
Traceback (most recent call last):
File "reproduce.py", line 59, in <module>
queried_item = items_table.get_item(id='first_id')
File "/home/aniket/venv/backend/local/lib/python2.7/site-packages/boto/dynamodb2/table.py", line 705, in get_item
consistent_read=consistent
File "/home/aniket/venv/backend/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 1099, in get_item
body=json.dumps(params))
File "/home/aniket/venv/backend/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 2842, in make_request
retry_handler=self._retry_handler)
File "/home/aniket/venv/backend/local/lib/python2.7/site-packages/boto/connection.py", line 954, in _mexe
status = retry_handler(response, i, next_sleep)
File "/home/aniket/venv/backend/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 2882, in _retry_handler
response.status, response.reason, data)
boto.dynamodb2.exceptions.ValidationException: ValidationException: 400 Bad Request
{u'Message': u'The number of conditions on the keys is invalid', u'__type': u'com.amazon.coral.validate#ValidationException'}
I am pretty sure I am doing something wrong, but I can't figure out what. The DynamoDB Docs mention that it is possible to query using only the HashKey, so what I am doing seems to be pretty normal.
我很确定我做错了什么,但我不知道是什么。DynamoDB文档中提到,只使用HashKey查询是可能的,所以我现在所做的似乎很正常。
In case it helps, I also added debug logging, and here's the output:
如果它有帮助,我还添加了调试日志记录,下面是输出:
(backend)aniket [~/PycharmProjects/website_backend] -> python reproduce.py ±[●●][master]
2015-04-15 20:04:48,218 [DEBUG] (boto) Using access key found in shared credential file.
2015-04-15 20:04:48,218 [DEBUG] (boto) Using secret key found in shared credential file.
2015-04-15 20:04:48,219 [DEBUG] (boto) Method: POST
2015-04-15 20:04:48,219 [DEBUG] (boto) Path: /
2015-04-15 20:04:48,219 [DEBUG] (boto) Data: {"GlobalSecondaryIndexes": [{"KeySchema": [{"KeyType": "HASH", "AttributeName": "color"}, {"KeyType": "RANGE", "AttributeName": "rating"}], "IndexName": "global_all_index_color", "Projection": {"ProjectionType": "ALL"}, "ProvisionedThroughput": {"WriteCapacityUnits": 5, "ReadCapacityUnits": 5}}], "AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"}, {"AttributeName": "rating", "AttributeType": "S"}, {"AttributeName": "seats", "AttributeType": "S"}, {"AttributeName": "color", "AttributeType": "S"}], "LocalSecondaryIndexes": [{"KeySchema": [{"KeyType": "HASH", "AttributeName": "id"}, {"KeyType": "RANGE", "AttributeName": "seats"}], "IndexName": "local_all_index_seats", "Projection": {"ProjectionType": "ALL"}}], "ProvisionedThroughput": {"WriteCapacityUnits": 1, "ReadCapacityUnits": 1}, "TableName": "items", "KeySchema": [{"KeyType": "HASH", "AttributeName": "id"}, {"KeyType": "RANGE", "AttributeName": "rating"}]}
2015-04-15 20:04:48,219 [DEBUG] (boto) Headers: {'Host': 'localhost', 'Content-Type': 'application/x-amz-json-1.0', 'Content-Length': '942', 'X-Amz-Target': 'DynamoDB_20120810.CreateTable'}
2015-04-15 20:04:48,219 [DEBUG] (boto) Host: localhost
2015-04-15 20:04:48,219 [DEBUG] (boto) Port: 8000
2015-04-15 20:04:48,219 [DEBUG] (boto) Params: {}
2015-04-15 20:04:48,219 [DEBUG] (boto) establishing HTTP connection: kwargs={'port': 8000, 'timeout': 70}
2015-04-15 20:04:48,219 [DEBUG] (boto) Token: None
2015-04-15 20:04:48,219 [DEBUG] (boto) CanonicalRequest:
POST
/
host:localhost
x-amz-date:20150415T143448Z
x-amz-target:DynamoDB_20120810.CreateTable
host;x-amz-date;x-amz-target
4d4b471da224cff0353d444ba9f31ecbda7ac332b618c8db038940477cf5fbd9
2015-04-15 20:04:48,219 [DEBUG] (boto) StringToSign:
AWS4-HMAC-SHA256
20150415T143448Z
20150415/localhost/localhost/aws4_request
a54fd62c95217cf6fafe69876388ac3ae8ffd4b2d87e23f71a131741d3e64792
2015-04-15 20:04:48,219 [DEBUG] (boto) Signature:
51e3035fcfef8b31f8d6c0e22779ba4b17990d3f91f8dfda6b70e559ee5c384e
2015-04-15 20:04:48,220 [DEBUG] (boto) Final headers: {'Content-Length': '942', 'User-Agent': 'Boto/2.38.0 Python/2.7.6 Linux/3.16.0-30-generic', 'Host': 'localhost', 'X-Amz-Date': '20150415T143448Z', 'X-Amz-Target': 'DynamoDB_20120810.CreateTable', 'Content-Type': 'application/x-amz-json-1.0', 'Authorization': 'AWS4-HMAC-SHA256 Credential=AKIAJW2Q5MT375WFZIMA/20150415/localhost/localhost/aws4_request,SignedHeaders=host;x-amz-date;x-amz-target,Signature=51e3035fcfef8b31f8d6c0e22779ba4b17990d3f91f8dfda6b70e559ee5c384e'}
2015-04-15 20:04:49,004 [DEBUG] (boto) Response headers: [('x-amzn-requestid', 'e4cd23ec-ad5a-4f94-8d80-dd9f002b0f28'), ('content-length', '1160'), ('content-type', 'application/x-amz-json-1.0'), ('x-amz-crc32', '175075191'), ('server', 'Jetty(8.1.12.v20130726)')]
2015-04-15 20:04:49,004 [DEBUG] (boto) Saw HTTP status: 200
2015-04-15 20:04:49,004 [DEBUG] (boto) Validating crc32 checksum for body: {"TableDescription":{"AttributeDefinitions":[{"AttributeName":"id","AttributeType":"S"},{"AttributeName":"rating","AttributeType":"S"},{"AttributeName":"seats","AttributeType":"S"},{"AttributeName":"color","AttributeType":"S"}],"TableName":"items","KeySchema":[{"AttributeName":"id","KeyType":"HASH"},{"AttributeName":"rating","KeyType":"RANGE"}],"TableStatus":"ACTIVE","CreationDateTime":1429108488.651,"ProvisionedThroughput":{"LastIncreaseDateTime":0.000,"LastDecreaseDateTime":0.000,"NumberOfDecreasesToday":0,"ReadCapacityUnits":1,"WriteCapacityUnits":1},"TableSizeBytes":0,"ItemCount":0,"LocalSecondaryIndexes":[{"IndexName":"local_all_index_seats","KeySchema":[{"AttributeName":"id","KeyType":"HASH"},{"AttributeName":"seats","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"},"IndexSizeBytes":0,"ItemCount":0}],"GlobalSecondaryIndexes":[{"IndexName":"global_all_index_color","KeySchema":[{"AttributeName":"color","KeyType":"HASH"},{"AttributeName":"rating","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"},"IndexStatus":"ACTIVE","ProvisionedThroughput":{"ReadCapacityUnits":5,"WriteCapacityUnits":5},"IndexSizeBytes":0,"ItemCount":0}]}}
2015-04-15 20:04:49,004 [DEBUG] (boto) {"TableDescription":{"AttributeDefinitions":[{"AttributeName":"id","AttributeType":"S"},{"AttributeName":"rating","AttributeType":"S"},{"AttributeName":"seats","AttributeType":"S"},{"AttributeName":"color","AttributeType":"S"}],"TableName":"items","KeySchema":[{"AttributeName":"id","KeyType":"HASH"},{"AttributeName":"rating","KeyType":"RANGE"}],"TableStatus":"ACTIVE","CreationDateTime":1429108488.651,"ProvisionedThroughput":{"LastIncreaseDateTime":0.000,"LastDecreaseDateTime":0.000,"NumberOfDecreasesToday":0,"ReadCapacityUnits":1,"WriteCapacityUnits":1},"TableSizeBytes":0,"ItemCount":0,"LocalSecondaryIndexes":[{"IndexName":"local_all_index_seats","KeySchema":[{"AttributeName":"id","KeyType":"HASH"},{"AttributeName":"seats","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"},"IndexSizeBytes":0,"ItemCount":0}],"GlobalSecondaryIndexes":[{"IndexName":"global_all_index_color","KeySchema":[{"AttributeName":"color","KeyType":"HASH"},{"AttributeName":"rating","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"},"IndexStatus":"ACTIVE","ProvisionedThroughput":{"ReadCapacityUnits":5,"WriteCapacityUnits":5},"IndexSizeBytes":0,"ItemCount":0}]}}
Table created
2015-04-15 20:04:49,004 [DEBUG] (boto) Method: POST
2015-04-15 20:04:49,004 [DEBUG] (boto) Path: /
2015-04-15 20:04:49,004 [DEBUG] (boto) Data: {"Expected": {"category": {"Exists": false}, "rating": {"Exists": false}, "id": {"Exists": false}, "color": {"Exists": false}, "seats": {"Exists": false}}, "Item": {"category": {"S": "Sofa"}, "rating": {"S": "4"}, "id": {"S": "first_id"}, "color": {"S": "beige"}, "seats": {"S": "6"}}, "TableName": "items"}
2015-04-15 20:04:49,004 [DEBUG] (boto) Headers: {'Host': 'localhost', 'Content-Type': 'application/x-amz-json-1.0', 'Content-Length': '307', 'X-Amz-Target': 'DynamoDB_20120810.PutItem'}
2015-04-15 20:04:49,005 [DEBUG] (boto) Host: localhost
2015-04-15 20:04:49,005 [DEBUG] (boto) Port: 8000
2015-04-15 20:04:49,005 [DEBUG] (boto) Params: {}
2015-04-15 20:04:49,005 [DEBUG] (boto) Token: None
2015-04-15 20:04:49,005 [DEBUG] (boto) CanonicalRequest:
POST
/
host:localhost
x-amz-date:20150415T143449Z
x-amz-target:DynamoDB_20120810.PutItem
host;x-amz-date;x-amz-target
96fd2aee6eabd2c812d7111c9a47ba21c31ccc86859c963cfa3fd69a18edc957
2015-04-15 20:04:49,005 [DEBUG] (boto) StringToSign:
AWS4-HMAC-SHA256
20150415T143449Z
20150415/localhost/localhost/aws4_request
9ed70485aa9e7036fd2db89e34036c9e24a3c91b6e35dbb7fc2cd476b4766f21
2015-04-15 20:04:49,005 [DEBUG] (boto) Signature:
1d81bae229584b7466c6951a71010c8e2d7a441e80b2e9b5a60d9782859345dc
2015-04-15 20:04:49,005 [DEBUG] (boto) Final headers: {'Content-Length': '307', 'User-Agent': 'Boto/2.38.0 Python/2.7.6 Linux/3.16.0-30-generic', 'Host': 'localhost', 'X-Amz-Date': '20150415T143449Z', 'X-Amz-Target': 'DynamoDB_20120810.PutItem', 'Content-Type': 'application/x-amz-json-1.0', 'Authorization': 'AWS4-HMAC-SHA256 Credential=AKIAJW2Q5MT375WFZIMA/20150415/localhost/localhost/aws4_request,SignedHeaders=host;x-amz-date;x-amz-target,Signature=1d81bae229584b7466c6951a71010c8e2d7a441e80b2e9b5a60d9782859345dc'}
2015-04-15 20:04:49,287 [DEBUG] (boto) Response headers: [('x-amzn-requestid', '80571386-1ce7-4f9b-84fb-6805a0dfa171'), ('content-length', '2'), ('content-type', 'application/x-amz-json-1.0'), ('x-amz-crc32', '2745614147'), ('server', 'Jetty(8.1.12.v20130726)')]
2015-04-15 20:04:49,287 [DEBUG] (boto) Saw HTTP status: 200
2015-04-15 20:04:49,287 [DEBUG] (boto) Validating crc32 checksum for body: {}
2015-04-15 20:04:49,287 [DEBUG] (boto) {}
New item saved
2015-04-15 20:04:49,288 [DEBUG] (boto) Method: POST
2015-04-15 20:04:49,288 [DEBUG] (boto) Path: /
2015-04-15 20:04:49,288 [DEBUG] (boto) Data: {"ConsistentRead": false, "TableName": "items", "Key": {"id": {"S": "first_id"}}}
2015-04-15 20:04:49,288 [DEBUG] (boto) Headers: {'Host': 'localhost', 'Content-Type': 'application/x-amz-json-1.0', 'Content-Length': '81', 'X-Amz-Target': 'DynamoDB_20120810.GetItem'}
2015-04-15 20:04:49,289 [DEBUG] (boto) Host: localhost
2015-04-15 20:04:49,289 [DEBUG] (boto) Port: 8000
2015-04-15 20:04:49,289 [DEBUG] (boto) Params: {}
2015-04-15 20:04:49,289 [DEBUG] (boto) Token: None
2015-04-15 20:04:49,289 [DEBUG] (boto) CanonicalRequest:
POST
/
host:localhost
x-amz-date:20150415T143449Z
x-amz-target:DynamoDB_20120810.GetItem
host;x-amz-date;x-amz-target
1563f0044c8fc746bb9a0ec2e4754e5fd03e62d604102f0745920d8c49481e88
2015-04-15 20:04:49,289 [DEBUG] (boto) StringToSign:
AWS4-HMAC-SHA256
20150415T143449Z
20150415/localhost/localhost/aws4_request
059601773b2e09d4c42f984cb185bf565e47a9dff8d42b3ae15dd61b4fc41f76
2015-04-15 20:04:49,289 [DEBUG] (boto) Signature:
e22cfe8b3e3e03dfa4e05ec11f333f9aaff0edcdbf498ebfa9d0e7dc5b452916
2015-04-15 20:04:49,290 [DEBUG] (boto) Final headers: {'Content-Length': '81', 'User-Agent': 'Boto/2.38.0 Python/2.7.6 Linux/3.16.0-30-generic', 'Host': 'localhost', 'X-Amz-Date': '20150415T143449Z', 'X-Amz-Target': 'DynamoDB_20120810.GetItem', 'Content-Type': 'application/x-amz-json-1.0', 'Authorization': 'AWS4-HMAC-SHA256 Credential=AKIAJW2Q5MT375WFZIMA/20150415/localhost/localhost/aws4_request,SignedHeaders=host;x-amz-date;x-amz-target,Signature=e22cfe8b3e3e03dfa4e05ec11f333f9aaff0edcdbf498ebfa9d0e7dc5b452916'}
2015-04-15 20:04:49,315 [DEBUG] (boto) Response headers: [('x-amzn-requestid', '51547354-f266-4870-8c79-6192e7d7c7b5'), ('content-length', '118'), ('content-type', 'application/x-amz-json-1.0'), ('server', 'Jetty(8.1.12.v20130726)')]
2015-04-15 20:04:49,316 [DEBUG] (boto) Saw HTTP status: 400
2015-04-15 20:04:49,316 [DEBUG] (boto) {"__type":"com.amazon.coral.validate#ValidationException","Message":"The number of conditions on the keys is invalid"}
Traceback (most recent call last):
File "reproduce.py", line 71, in <module>
queried_item = items_table.get_item(id='first_id')
File "/home/aniket/venv/backend/local/lib/python2.7/site-packages/boto/dynamodb2/table.py", line 705, in get_item
consistent_read=consistent
File "/home/aniket/venv/backend/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 1099, in get_item
body=json.dumps(params))
File "/home/aniket/venv/backend/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 2842, in make_request
retry_handler=self._retry_handler)
File "/home/aniket/venv/backend/local/lib/python2.7/site-packages/boto/connection.py", line 954, in _mexe
status = retry_handler(response, i, next_sleep)
File "/home/aniket/venv/backend/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 2882, in _retry_handler
response.status, response.reason, data)
boto.dynamodb2.exceptions.ValidationException: ValidationException: 400 Bad Request
{u'Message': u'The number of conditions on the keys is invalid', u'__type': u'com.amazon.coral.validate#ValidationException'}
1 个解决方案
#1
14
GetItem
in DynamoDB needs the same number of key conditions as the number of keys, largely because the operation must find the exact item in the table. For the primary key, you must provide all of the attributes. There should be only one item, if any, matching the Get expectations. This is written in the DynamoDB doc.
DynamoDB中的GetItem需要与密钥数目相同的关键条件,这很大程度上是因为操作必须找到表中的精确项。对于主键,必须提供所有属性。应该只有一个项目,如果有的话,匹配得到的期望。这是在DynamoDB doc中写的。
On contrast, you can use Query
to get multiple (possibly) items for a given condition. Since you know this I believe, I think you mistakenly used the wrong get_item()
api, instead of query()
or something alike.
相反,您可以使用查询来获得给定条件的多个(可能)项。因为您知道这一点,所以我认为您错误地使用了错误的get_item() api,而不是查询()或类似的东西。
#1
14
GetItem
in DynamoDB needs the same number of key conditions as the number of keys, largely because the operation must find the exact item in the table. For the primary key, you must provide all of the attributes. There should be only one item, if any, matching the Get expectations. This is written in the DynamoDB doc.
DynamoDB中的GetItem需要与密钥数目相同的关键条件,这很大程度上是因为操作必须找到表中的精确项。对于主键,必须提供所有属性。应该只有一个项目,如果有的话,匹配得到的期望。这是在DynamoDB doc中写的。
On contrast, you can use Query
to get multiple (possibly) items for a given condition. Since you know this I believe, I think you mistakenly used the wrong get_item()
api, instead of query()
or something alike.
相反,您可以使用查询来获得给定条件的多个(可能)项。因为您知道这一点,所以我认为您错误地使用了错误的get_item() api,而不是查询()或类似的东西。