在DynamoDB中放置/更新项目时,由于UpdateExpression语法,操作失败

10

我创建了一个DynamoDB表,在我的Python代码中,我初始化资源如下:

self.dynamodb = self.session.resource('dynamodb').Table('aws-ci')

这个表只有一个索引/关键字,名称为environment。我想要将以下对象 PUT 到表中:

{
  "environment": "beta",
  "X": {
    "current_sha": "sha1",
    "deployed": true,
    "prev_sha": "sha2",
    "status": "inactive"
  },
  "Y-Z": {
    "current_sha": "sha1",
    "deployed": false,
    "prev_sha": "sha2",
    "status": "active"
  }
}

在这里,XY-Z是微服务的名称。我的插入代码如下:

def put_service_data(self, environment, service_name, service_data, status = None):
    get_previous = self.dynamodb.get_item(
        Key = {
            'environment': environment
        }
    ).get(service_name)
    service_data['prev'] = get_previous and get_previous.get('current_sha') or 'NULL'
    if status == 'rollback' and get_previous:
        service_data['current'] = get_previous.get('current_sha')
        service_data['prev'] = get_previous.get('prev_sha')
    set_query = "SET {0}.current_sha = :current, {0}.prev_sha = :prev, {0}.deployed = :is_deployed, {0}.current_status = :status".format(service_name)
    updated = self.dynamodb.update_item(
        Key = {
            'environment': environment
        },
        UpdateExpression = set_query,
        ExpressionAttributeValues = {
            ':current': service_data.get('current'),
            ':prev': service_data.get('prev'),
            ':status': service_data.get('status'),
            ':is_deployed': service_data.get('deployed')
        },
        ReturnValues = "ALL_NEW"
    )
    return updated

以前,我使用的是{0}.status而不是{0}.current_status,但是这会引发以下错误:

调用UpdateItem操作时出错(ValidationException):无效的UpdateExpression:属性名是保留关键字;保留关键字:status

无论如何,我将属性名称更改为current_status并再次尝试插入,但是这一次收到以下消息:

调用UpdateItem操作时出错(ValidationException):提供给更新表达式的文档路径无效

在尝试为服务X设置属性时,我收到了上述消息,在尝试为Y-Z设置属性时,则收到以下消息:

调用UpdateItem操作时出错(ValidationException):无效的UpdateExpression:语法错误;标记:"-", 附近:"Y-Z"

我目前无法理解update_item调用应该如何工作。
1个回答

17

你尝试过这个吗? http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ExpressionPlaceholders.html#ExpressionAttributeNames

set_query = "SET #service_name.current_sha = :current, #service_name.prev_sha = :prev, #service_name.deployed = :is_deployed, #service_name.current_status = :current_status"
updated = self.dynamodb.update_item(
    Key = {
        'environment': environment
    },
    UpdateExpression = set_query,
    ExpressionAttributeValues = {
        ':current': service_data.get('current'),
        ':prev': service_data.get('prev'),
        ':current_status': service_data.get('status'),
        ':is_deployed': service_data.get('deployed')
    },
    ExpressionAttributeNames = {
         '#service_name': service_name,
    },
    ReturnValues = "ALL_NEW"
)

是的,就是这样。:/ 我不知道我怎么在文档中错过了那个参数。 - hjpotter92
如果我将 current_status 改回 status,这样行得通吗? - hjpotter92
如果您这样做,那么您需要将状态添加到ExpressionAttributeNames中。 - ananth krishnan

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