使用Python / Boto更新DynamoDB原子计数器 [英] Update DynamoDB Atomic Counter with Python / Boto

查看:104
本文介绍了使用Python / Boto更新DynamoDB原子计数器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Python Boto 2.3.0更新原子计数计数器,但是找不到该操作的文档。

I am trying to update an atomic count counter with Python Boto 2.3.0, but can find no documentation for the operation.

似乎没有直接接口,所以我尝试使用layer1界面进行原始更新,但即使是简单的更新也无法完成。

It seems there is no direct interface, so I tried to go to "raw" updates using the layer1 interface, but I was unable to complete even a simple update.

我尝试了以下变体,但全部没有运气

I tried the following variations but all with no luck

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

他们都产生相同的错误:

They all produce the same error:

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

我还此处调查了API文档他们是很斯巴达人。

I also investigated the API docs here but they were pretty spartan.

我做了很多搜索和摆弄,而我剩下的唯一事情就是使用PHP API并深入研究代码来查找它在哪里格式化 JSON主体,但这有点麻烦。

I have done a lot of searching and fiddling, and the only thing I have left is to use the PHP API and dive into the code to find where it "formats" the JSON body, but that is a bit of a pain. Please save me from that pain!

推荐答案

对不起,我误会了您的期望。您可以通过layer2完成此操作,尽管有一个小错误需要解决。以下是一些Layer2代码:

Sorry, I misunderstood what you were looking for. You can accomplish this via layer2 although there is a small bug that needs to be addressed. Here's some Layer2 code:

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

这将导致与您在Layer1代码中执行的在线请求相同,如以下调试输出所示。

This results in the same over-the-wire request as you are performing in your Layer1 code, as shown by the following debug output.

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

如果要避免最初的GetItem调用,可以改为执行以下操作:

If you want to avoid the initial GetItem call, you could do this instead:

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

这将更新项(如果已存在)或创建它(如果尚不存在)。

Which will update the item if it already exists or create it if it doesn't yet exist.

这篇关于使用Python / Boto更新DynamoDB原子计数器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆