Jas*_*igh 9 python counter atomic boto amazon-dynamodb
我正在尝试使用Python Boto 2.3.0更新原子计数计数器,但是找不到该操作的文档.
似乎没有直接接口,所以我尝试使用layer1接口进行"原始"更新,但我甚至无法完成简单的更新.
我尝试了以下变化,但都没有运气
dynoConn.update_item(INFLUENCER_DATA_TABLE,
{'HashKeyElement': "9f08b4f5-d25a-4950-a948-0381c34aed1c"},
{'new': {'Value': {'N':"1"}, 'Action': "ADD"}})
dynoConn.update_item('influencer_data',
{'HashKeyElement': "9f08b4f5-d25a-4950-a948-0381c34aed1c"},
{'new': {'S' :'hello'}})
dynoConn.update_item("influencer_data",
{"HashKeyElement": "9f08b4f5-d25a-4950-a948-0381c34aed1c"},
{"AttributesToPut" : {"new": {"S" :"hello"}}})
Run Code Online (Sandbox Code Playgroud)
它们都会产生相同的错误:
File "/usr/local/lib/python2.6/dist-packages/boto-2.3.0-py2.6.egg/boto/dynamodb/layer1.py", line 164, in _retry_handler
data)
boto.exception.DynamoDBResponseError: DynamoDBResponseError: 400 Bad Request
{u'Message': u'Expected null', u'__type': u'com.amazon.coral.service#SerializationException'}
Run Code Online (Sandbox Code Playgroud)
我做了很多搜索和摆弄,我唯一剩下的就是使用PHP API并深入研究代码以找到它"格式化"JSON主体的位置,但这有点痛苦.请救我脱离这种痛苦!
gar*_*aat 12
对不起,我误解了你在找什么.您可以通过layer2完成此操作,尽管有一个小错误需要解决.这是一些Layer2代码:
>>> import boto
>>> c = boto.connect_dynamodb()
>>> t = c.get_table('counter')
>>> item = t.get_item('counter')
>>> item
{u'id': 'counter', u'n': 1}
>>> item.add_attribute('n', 20)
>>> item.save()
{u'ConsumedCapacityUnits': 1.0}
>>> item # Here's the bug, local Item is not updated
{u'id': 'counter', u'n': 1}
>>> item = t.get_item('counter') # Refetch item just to verify change occurred
>>> item
{u'id': 'counter', u'n': 21}
Run Code Online (Sandbox Code Playgroud)
这导致与您在Layer1代码中执行的相同的线上请求,如以下调试输出所示.
2012-04-27 04:17:59,170 foo [DEBUG]:StringToSign:
POST
/
host:dynamodb.us-east-1.amazonaws.com
x-amz-date:Fri, 27 Apr 2012 11:17:59 GMT
x-amz-security- token:<removed> ==
x-amz-target:DynamoDB_20111205.UpdateItem
{"AttributeUpdates": {"n": {"Action": "ADD", "Value": {"N": "20"}}}, "TableName": "counter", "Key": {"HashKeyElement": {"S": "counter"}}}
Run Code Online (Sandbox Code Playgroud)
如果你想避免初始的GetItem调用,你可以这样做:
>>> import boto
>>> c = boto.connect_dynamodb()
>>> t = c.get_table('counter')
>>> item = t.new_item('counter')
>>> item.add_attribute('n', 20)
>>> item.save()
{u'ConsumedCapacityUnits': 1.0}
Run Code Online (Sandbox Code Playgroud)
如果该项目已存在,则会更新该项目,如果该项目尚不存在,则创建该项目.
对于那些寻找答案的人我已经找到了.首先重要说明,我目前还没有意识到目前发生了什么,要获得一个我必须执行以下操作的layer1实例:
import boto
AWS_ACCESS_KEY=XXXXX
AWS_SECRET_KEY=YYYYY
dynoConn = boto.connect_dynamodb(AWS_ACCESS_KEY, AWS_SECRET_KEY)
dynoConnLayer1 = boto.dynamodb.layer1.Layer1(AWS_ACCESS_KEY, AWS_SECRET_KEY)
Run Code Online (Sandbox Code Playgroud)
基本上实例化第2层第一层,然后是第1层.也许我做了一些愚蠢的事情但是在这一点上我很高兴能让它工作......我稍后会对细节进行排序.然后......实际进行原子更新调用:
dynoConnLayer1.update_item("influencer_data",
{"HashKeyElement":{"S":"9f08b4f5-d25a-4950-a948-0381c34aed1c"}},
{"direct_influence":
{"Action":"ADD","Value":{"N":"20"}}
}
);
Run Code Online (Sandbox Code Playgroud)
请注意,在上面的示例中,Dynamo将ADD 20添加到当前值,并且此操作将是原子意义,意味着在"同一时间"发生的其他操作将在新值建立为+20后正确"调度"发生或执行此操作之前.无论哪种方式,都将实现期望的效果.
确保在layer1连接的实例上执行此操作,因为layer2将抛出错误,因为它需要一组不同的参数类型.
这里的所有都是它的!!!!大家都知道,我用PHP SDK来解决这个问题.安装和设置的时间非常短.当您进行呼叫时,调试数据实际上会显示HTTP请求主体的格式,因此您可以在示例后复制/建模您的layer1参数.这是我用来在PHP中进行原子更新的代码:
<?php
// Instantiate the class
$dynamodb = new AmazonDynamoDB();
$update_response = $dynamodb->update_item(array(
'TableName' => 'influencer_data',
'Key' => array(
'HashKeyElement' => array(
AmazonDynamoDB::TYPE_STRING=> '9f08b4f5-d25a-4950-a948-0381c34aed1c'
)
),
'AttributeUpdates' => array(
'direct_influence' => array(
'Action' => AmazonDynamoDB::ACTION_ADD,
'Value' => array(
AmazonDynamoDB::TYPE_NUMBER => '20'
)
)
)
));
// status code 200 indicates success
print_r($update_response);
?>
Run Code Online (Sandbox Code Playgroud)
希望这将有助于其他人直到Boto layer2接口赶上...或者有人只是想知道如何在level2中做到这一点:-)
| 归档时间: |
|
| 查看次数: |
6235 次 |
| 最近记录: |