如何重命名DynamoDB列/键

12
在我的DynamoDb表中,我有一个名为“status”的列/键,结果证明它是一个保留关键字。不幸的是,删除整个表并重新初始化它不是一个选项。如何重命名该键?
这是导致异常的Lambda代码:
try :
            response = table.query(
                IndexName='myId-index',
                KeyConditionExpression=Key('myId').eq(someId)
            )
            for item in response['Items']:
                print('Updating Item: ' + item['id'])
                table.update_item(
                    Key={
                        'id': item['id']
                    },
                    UpdateExpression='SET myFirstKey = :val1, mySecondKey = :val2, myThirdKey = :val3, myFourthKey = :val4, myFifthKey = :val5, status = :val6',
                    ExpressionAttributeValues={
                        ':val1': someValue1,
                        ':val2': someValue2,
                        ':val3': someValue3,
                        ':val4': someValue4,
                        ':val5': someValue5,
                        ':val6': someValue6
                    }
                )
except Exception, e:
            print ('ok error: %s' % e)

这里是异常情况:

2016-06-14 18:47:24 UTC+2 出错了:调用UpdateItem操作时发生ValidationException错误:无效的UpdateExpression:属性名是保留关键字;保留关键字:status


https://forums.aws.amazon.com/thread.jspa?threadID=91491 - Iłya Bursov
谢谢您的回答。问题是,由于该键是保留关键字,我无法以编程方式访问它。Lambda会抛出一个错误。因此,没有办法将其值复制到新键并清除旧键。我无法手动完成此操作。记录太多了。 :( - weka1
嗨@weka1,欢迎来到SO或类似的地方...SO不是1)代码外包设施2)代码工厂。 SO是1)一个需要你将问题一分为二的网站2)由志愿者运行,例如我们不会因提供帮助而获得薪酬3)阅读此文章以获取有关在StackOverflow上获得良好答案的信息http: //odedcoster.com/blog/2010/07/28/getting-good-answers-on-stackoverflow-part-1-of-n/ - Andy K
3个回答

13

重命名一个列没有简单的方法。你需要为每个条目创建一个新属性,然后删除现有属性的所有值。

如果查询表格时出现问题,没有必要删除您的属性/列,您可以使用表达式属性名称来解决。

表达式属性名称文档中可以了解:

在某些情况下,您可能需要编写包含DynamoDB保留字冲突的属性名称的表达式...为了解决这个问题,您可以定义一个表达式属性名称。表达式属性名称是您在表达式中使用的占位符,可替代实际属性名称。


1
感谢您的快速回复。问题不在于查询数据,而是我无法以编程方式访问问题关键字中的数据,因为Lambda会给我一个关键字错误。因此,也没有办法将值仅复制到新键并清除旧键。 :( - weka1
你是使用 Lambda 获取数据吗?还是使用 DynamoDB Streams? - Shibashis
我不太确定你的意思。数据通过由S3触发的Lambda进入DynamoDB。我通过iOS SDK将其提取到我的应用程序中,并尝试通过Lambda在此表中更改值时更新其他各种表格。但是,如果我尝试读取/写入与DynamoDB关键字同名的键中存储的值,Lambda会崩溃/抛出异常。 - weka1
明白了,你能分享一下抛出异常的代码片段吗? - Shibashis
谢谢,我已经将代码添加到原始问题中了! - weka1
1
我花了一些时间,但你一直是对的。在update_item表达式中添加Expression Attribute Names确实使它工作了。谢谢! - weka1

5

不必重命名列,有一个简单的解决方案:在查询中使用投影表达式和表达式属性名称。

我遇到了同样的问题(我的表包含列“name”)。下面是一个示例查询:

TableName: 'xxxxxxxxxx',
  ExpressionAttributeNames: {
    '#A': 'country',
    '#B': 'postcode',
    '#C': 'name'
  },
  ExpressionAttributeValues: {
    ':a': {S: 'DE'},
    ':c': {S: 'Peter Benz'}
  },
  FilterExpression: 'country = :a AND #C = :c',
  ProjectionExpression: '#A, #B, #C'

1
使用NoSQL Workbench应用程序,AWS支持我导出了一个拥有我想要更改列名的表格的副本。我打开了NoSQL Workbench创建的JSON文件,然后对所涉及的列名进行了简单的查找/替换操作。
在.JSON文件上看起来正确的名称之后,我使用NoSQL应用程序将表格重新导入到dynamodb中。导入将覆盖现有数据,从而清除错误的列名。
如果您有一个巨大的数据集,则下载副本到本地计算机可能不是一个好的解决方案,但对于我的小表格来说,它运行得相当不错。

我认为在该应用程序中没有办法导出超过100个项目的表格。 - jcollum
有一种替代方法可以将DynamoDB导出到S3,使用时间点恢复 - 它以特殊的JSON格式导出数据,该格式由Boto3支持。因此,您可以导出到S3,在S3中分块解析它,并导入回Dynamo。 - Alex Medveshchek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接