如何在dynamodb中添加空或数据映射?

时间:2016-02-23 05:42:24

标签: amazon-dynamodb

我有这样的事情:

{
  Records:{}
}

我只想在这样的记录中添加数据:

{
  Id: 123,
  Records:{
    10001: { event : "item1" }
  }
}

我的第一次尝试:

var params = {
    TableName : "Records",
    Key : { Id : 123 },
    UpdateExpression: 'set Record.#k1.event = :v1',
    ExpressionAttributeNames: { '#k1' :  10001},
    ExpressionAttributeValues: { ':v1' : 'item1' }
};

因为Record.10001不存在,所以它给了我错误:

The document path provided in the update expression is invalid for update

" ADD"只支持NUMBER和SET类型,所以它不适合我的情况。

我的第二次尝试(尝试创建一张空地图):

var params = {
    TableName : "Records",
    Key : { Id : 123 },
    UpdateExpression: 'set Record.#k1 = {}',
    ExpressionAttributeNames: { '#k1' :  10001},
};

它失败了,因为我的语法可能不正确,我找不到如何为属性创建一个空映射。

所以我的问题是如何将结构化对象作为地图或空地图添加到现有项目,如上例所示?

我可以轻松地修改亚马逊DynamoDB数据管理页面中的数据,所以至少我知道有一种方法可以做到这一点。我只需知道如何。

由于

4 个答案:

答案 0 :(得分:3)

我以某种方式成功地这样做了:

var params = {
    TableName: "Records",
    Key: { Id: 123 },
    UpdateExpression: 'set Records.#k1 = :v1',
    ExpressionAttributeNames: {'#k1': '10001',},
    ExpressionAttributeValues: {':v1': { event: 'Yay~' } }
};

可选择使用

    UpdateExpression: 'set Records.#k1 = if_not_exists( Records.#k1, :v1)',

避免覆盖现有记录。

答案 1 :(得分:1)

摆脱这种问题的一种可能的解决方案:您必须事先创建一个空对象并存在于数据库中。

例如

  1. 在对象生成期间(在DB中原始创建):

    字段:{}

  2. 要更新此字段,请使用:

        TableName: ....,
        Key: {
            .....
        },
        UpdateExpression: 'set field.#mapKey = :v',
        ExpressionAttributeNames: {
            '#mapKey': myName
        },
        ExpressionAttributeValues: {
            ':v': myValue
        }
    

答案 2 :(得分:0)

我找到了我们得到的错误的解决方法。

try:
    table.update_item( 
          Key = {'Id' : id},
          UpdateExpression = 'SET Records.#key1.#key2 = :value1',
          ExpressionAttributeNames = {'#key1': '10001', '#key2' : 'event'},
          ExpressionAttributeValues = {':value1': 'singing'}
         )
except:
    table.update_item( 
          Key = {'Id' : id},
          UpdateExpression = 'SET Records = :value1',
          ExpressionAttributeValues = {':value1': {'10001': {'event' : 'dance'}}}
          )

当我们第一次尝试更新时,我们得到"更新表达式中提供的文档路径对于更新"错误。将抛出异常,因为没有嵌套的JSON。

此后,任何更新都说例如Record.10002不会抛出异常。将执行try块中的更新功能。

如果这是处理这种情况的正确方法,请对此发表评论。

答案 3 :(得分:-1)

为了基于给定的字典使用各种键动态地插入/更新Dynamodb项(最终是Dynamodb中的列),我们可以构造查询字符串,如下所示:

# given dictionary with needs to be dumped into dynamodb
dict_to_insert = {'column1':'value1', 
                  'column2.subdocument1':{'subkey1':'subvalue1',
                                          'subkey2':'subvalue2'}...}...

# placeholder variables
# Using upsert for insert/update mllog records on dynamodb
query = "SET"
values_dict = {}
names_dict = {}
i = 0

# iterating over given dictionary and construct the query
for key, value in dict_to_insert.items():

        # if item key column provide in the given dictionary
        # then it should be skipped
        if key == 'ITEM_KEY_NAME':
            i += 1
            continue

        # None values causing error on update_item 
        # So, better to ignore them as well
        if value is not None:

            # if_not_exists method prevents overwriting existing 
            # values on columns
            query += " " + "#k_" + str(i) + " = if_not_exists(#k_" + str(i) + \
                     ", :v_" + str(i)+")"
            if key != list(dict_to_insert.keys())[-1]:  # if not the last attribute add ,
                query += ","

            # Defining dynamodb columns and their corresponding values
            values_dict["#k_" + str(i)] = key
            names_dict[":v_" + str(i)] = value
        i += 1

一旦我们按照上面所示构造查询字符串,就可以放心地在Dy​​namodb上运行我们的update_item方法:

# table obj here is boto3 dynamodb resource instance
table.update_item(
    TableName='DYNAMODB_TABLENAME',
    Key={'ITEM_KEY_NAME': 'ANY_VALUE_AS_KEY'},
    UpdateExpression=query.strip(),
    ExpressionAttributeNames=names_dict,
    ExpressionAttributeValues=values_dict)