2015-04-15 15 views
9

Tôi chỉ làm một nhiệm vụ đơn giản trong DynamoDB:Dynamodb2 Table.get_item() throws ValidationException "Số lượng các điều kiện trên các phím không hợp lệ"

  1. Tạo một Table,
  2. thêm một mục vào nó
  3. Truy vấn bảng cho mục đó.

Dưới đây là một kịch bản mà tôi đang sử dụng:

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

Khi tôi chạy kịch bản này, tôi nhận được một 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'} 

Tôi khá chắc chắn tôi đang làm điều gì sai, nhưng Tôi không thể hiểu được điều gì. Tài liệu DynamoDB đề cập rằng có thể truy vấn bằng cách sử dụng chỉ HashKey, vì vậy những gì tôi đang làm có vẻ khá bình thường.

Trong trường hợp nó giúp, tôi cũng nói thêm debug logging, và đây là kết quả:

(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'} 

Trả lời

14

GetItem trong DynamoDB cần cùng một số điều kiện quan trọng như số lượng các phím, chủ yếu là do hoạt động phải tìm ra mục chính xác trong bảng. Đối với khóa chính, bạn phải cung cấp tất cả các thuộc tính. Chỉ nên có một mục, nếu có, phù hợp với các yêu cầu Nhận được. Điều này được viết trong DynamoDB doc.

Ngược lại, bạn có thể sử dụng Query để nhận nhiều mục (có thể) cho một điều kiện nhất định. Vì bạn biết điều này tôi tin, tôi nghĩ bạn đã sử dụng sai số get_item() api, thay vì query() hoặc thứ gì đó giống nhau.

+0

Điều đó có ý nghĩa. Vì một lý do nào đó, tôi đã có ấn tượng rằng get_item() sẽ sử dụng API truy vấn nội bộ. – czardoz

Các vấn đề liên quan