上一节介绍了DynamoDB 的查询,原本计划这一节介绍使用索引的查询,不过随机看到了更新操做,就先写更新操做吧python
SQL 语言提供用于修改数据的 UPDATE 语句。DynamoDB 使用 UpdateItem 操做完成相似的任务。sql
在 SQL 中,可以使用 UPDATE 语句修改一个或多个行。SET 子句为一个或多个列指定新值,WHERE 子句肯定修改的行。示例以下:数据库
UPDATE Music SET RecordLabel = 'Global Records' WHERE Artist = 'No One You Know' AND SongTitle = 'Call Me Today';
若是任何行均不匹配 WHERE 子句,则 UPDATE 语句不起做用。express
在 DynamoDB 中,可以使用 UpdateItem 操做修改单个项目。json
API 语法以下:app
{ "AttributeUpdates": { "string" : { "Action": "string", "Value": { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } } }, "ConditionalOperator": "string", "ConditionExpression": "string", "Expected": { "string" : { "AttributeValueList": [ { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } ], "ComparisonOperator": "string", "Exists": boolean, "Value": { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } } }, "ExpressionAttributeNames": { "string" : "string" }, "ExpressionAttributeValues": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "Key": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "ReturnConsumedCapacity": "string", "ReturnItemCollectionMetrics": "string", "ReturnValues": "string", "TableName": "string", "UpdateExpression": "string" }
参数说明:函数
Key: 主键,用于定位项目code
TableName:表名 (最小 3. 最大 255)索引
Expected:图片
AttributeUpdates: 遗留参数,已废弃
ConditionalOperator: 遗留参数,已废弃
ConditionExpression:条件表达式(仅在特定 ConditionExpression 的计算结果为 true 时成功完成)
ExpressionAttributeNames:条件表达式的名称的别名,好比 date 为保留字,可用别名定义为 #d
ExpressionAttributeValues:条件表达式的值
ReturnConsumedCapacity:显示使用的写入容量单位数
TOTAL 会返回由表及其全部global secondary index占用的写入容量;
INDEXES 仅返回由global secondary index占用的写入容量;
NONE 表示您不须要返回任何占用容量统计数据。
ReturnValues: 更新后返回的数据.
NONE - 若是没有特别说明,返回None (这个是默认值)
ALL_OLD - 按在进行更新以前的状况,返回整个项目。
ALL_NEW - 按在进行更新以后的状况,返回整个项目。
UPDATED_OLD - 按在进行更新以前的状况,仅返回更新的值。
UPDATED_NEW - 按在进行更新以后的状况,仅返回更新的值。
UpdateExpression:指定要修改的属性以及这些属性的新值,更新表达式还指定如何修改属性。下面是更新表达式的语法摘要:
update-expression ::= SET set-action , ... | REMOVE remove-action , ... | ADD add-action , ... | DELETE delete-action , ...
更新表达式由多个部分组成。每一个部分以一个 SET、REMOVE、ADD 或 DELETE 关键字开头。您可在更新表达式中按任意顺序包含其中任意部分。可是,每一个部分关键字只能出现一次。您能够同时修改多个属性。如下是更新表达式的一些示例:
SET list[0] = :val1
REMOVE #m.nestedField1, #m.nestedField2
ADD aNumber :val2, anotherNumber :val3
DELETE aSet :val4
如下示例显示了带有多个部分的单个更新表达式:
SET list[0] = :val1 REMOVE #m.nestedField1, #m.nestedField2 ADD aNumber :val2, anotherNumber :val3 DELETE aSet :val4
咱们能够在更新表达式中使用任意属性名称,第一个字符是 a-z 或 A-Z,第二个字符(若是存在)是 a-z、A-Z 或 0-9。
若是属性名称不知足此要求,则须要将表达式属性名称定义为占位符。更多信息参考(表达式属性名称)。
要在更新表达式中指定文本值,可使用表达式属性值。更多信息参考(表达式属性值)。
在更新表达式中使用 SET 操做可将一个或多个属性与值添加到项目。若是这些属性已存在,则更新。还可使用 SET 来加或减数字类型的属性。对多个属性执行 SET 操做,使用逗号分隔。
set语法以下:
set-action ::= path = value value ::= operand | operand '+' operand | operand '-' operand operand ::= path | function
path 元素是项目的文档路径。(好比项目中info 为字典 info 中 a 的路径为info['a'])
operand 元素能够为项目的文档路径,或者为函数。
SET 操做支持如下函数:
if_not_exists (path, operand) - 若是项目在指定 path 中不包含属性,则 if_not_exists 的求值结果为 operand;不然求值结果为 path。您可使用此函数来避免覆盖项目中已存在的属性。
list_append (operand, operand) - 此函数的求值结果为列表,新元素将添加到列表中。新元素必须包含在列表中,例如要向列表中添加 2,操做数将成为 [2]。您能够经过反转操做数的顺序,将新元素附加到列表的开头或结尾。
如下是在这些函数中使用 SET 操做的一些示例。
若是属性已存在,则如下示例不执行任何操做;不然它会将属性设置为默认值。
SET Price = if_not_exists(Price, 100)
如下示例将新元素添加到 FiveStar 评论列表。表达式属性名称 #pr 是 ProductReviews;属性值 :r 是只包含一个元素的列表。若是列表以前有两个元素 [0] 和 [1],则新元素将为 [2]。
SET #pr.FiveStar = list_append(#pr.FiveStar, :r)
如下示例将另外一个元素添加到 FiveStar 评论列表中,但此时元素将附加到列表开头的位置 [0] 处。列表中的全部其余元素将会移动一位。
SET #pr.FiveStar = list_append(:r, #pr.FiveStar)
在更新表达式中使用 REMOVE 操做可从项目中删除一个或多个元素。要执行多个 REMOVE 操做,请使用逗号分隔。
下面是更新表达式中的 REMOVE 的语法摘要。惟一的操做数是您要删除的属性的文档路径:
remove-action ::= path
如下是使用 REMOVE 操做的更新表达式示例。从项目中删除多个属性:
REMOVE Title, RelatedItems[2], Pictures.RearView
对列表元素使用 REMOVE
当删除现有列表元素时,剩余的元素将会移位。例如,考虑如下列表:
MyNumbers: { ["Zero","One","Two","Three","Four"] }
列表包含元素 [0]、[1]、[2]、[3] 和 [4]。如今,咱们使用 REMOVE 操做删除两个元素:
REMOVE MyNumbers[1], MyNumbers[3]
剩余的元素会向右移位,生成带有元素 [0]、[1] 和 [2] 的列表,每一个元素具备如下数据:
MyNumbers: { ["Zero","Two","Four"] }
若是您使用 REMOVE 来删除超出列表中最后一个元素位置的不存在项目,则将不执行任何操做:也就是不删除任何数据。例如,如下表达式对 MyNumbers 列表没有任何效果:
REMOVE MyNumbers[11]
ADD 操做仅支持数字和集数据类型。通常而言,咱们建议使用 SET 而不是 ADD。
在更新表达式中使用 ADD 可执行如下任一操做:
若是属性尚不存在,则将新属性及其值添加到项目。
若是属性已存在,则 ADD 的行为取决于属性的数据类型:
若是属性是数字,而且添加的值也是数字,则该值将按数学运算与现有属性相加。(若是该值为负数,则从现有属性减去该值。)
若是属性是集,而且您添加的值也是集,则该值将附加到现有集中。
要执行多个 ADD 操做,请使用逗号分隔。
在如下语法摘要中:
path 元素是属性的文档路径。属性必须为数字或集数据类型。
value 元素是要与属性相加的值(对于数字数据类型),或者是要附加到属性中的集(对于集类型)。
add-action ::= path value
如下是使用 add 操做的一些更新表达式示例。
如下示例对数字进行加运算。表达式属性值 :n 是数字,此值将与 Price 相加。
ADD Price :n
如下示例将一个或多个值添加到 Color 集。表达式属性值 :c 是字符串集。
ADD Color :c
DELETE 操做只支持集数据类型。
在更新表达式中使用 DELETE 操做可从集中删除元素。要执行多个 DELETE 操做,请使用逗号分隔。
在如下语法摘要中:
path 元素是属性的文档路径。该属性必须是集数据类型。
value 元素是集中要删除的元素。
delete-action ::= path value
如下示例使用 DELETE 操做从 Color 集中删除元素。表达式属性值 :c 是字符串集。
DELETE Color :c
{ TableName: "Music", Key: { "Artist":"No One You Know", "SongTitle":"Call Me Today" }, UpdateExpression: "SET RecordLabel = :label", ExpressionAttributeValues: { ":label": "Global Records" } }
UpdateItem必须指定要修改的项目的 Key 属性和一个用于指定属性值的 UpdateExpression。
UpdateItem 替换整个项目,而不是替换单个属性。
UpdateItem 的行为与“upsert”操做的行为相似:若是项目位于表中,则更新项目,不然添加(插入)新项目。
UpdateItem只能修改单个项目,若是要修改多个项目,则必须使用多个 UpdateItem 操做。
UpdateItem 支持条件写入,在此状况下,操做仅在特定 ConditionExpression 的计算结果为 true 时成功完成。例如,除非歌曲的价格大于或等于 2.00,不然如下 UpdateItem 操做不会执行更新:
要执行条件更新,请使用更新表达式以及条件表达式来执行 UpdateItem 操做。要继续执行操做,条件表达式的求值结果必须为 true;不然操做将失败。
假设您要将某项目的价格提升必定金额,如 :amt,但前提是结果不得超过最高价。为此,您能够计算当前容许提价的最高价,而后从最高价中减去提升的金额 :amt。将结果定义为 :limit,而后使用如下条件表达式:
条件表达式:Price <= :limit)
更新表达式:SET Price = Price + :amt
如今假设您要为项目设置前视图图片,不过前提是该项目尚未任何图片,不但愿覆盖任何现有元素。您可使用如下表达式来执行操做:
更新表达式:SET Pictures.FrontView = :myUR
(假设 :myURL 是项目图片的位置,例如 http://example.com/picture.jpg。)
条件表达式:attribute_not_exists(Pictures.FrontView)
{ TableName: "Music", Key: { "Artist":"No One You Know", "SongTitle":"Call Me Today" }, UpdateExpression: "SET RecordLabel = :label", ConditionExpression: "Price >= :p", ExpressionAttributeValues: { ":label": "Global Records", ":p": 2.00 } }
UpdateItem 还支持原子计数器或类型为 Number 的属性(可递增或递减)。原子计数器在不少方面都相似于 SQL 数据库中的顺序生成器、身份列或自递增字段。
如下是一个 UpdateItem 操做的示例,它初始化一个新属性 (Plays) 来跟踪歌曲的已播放次数:
{ TableName: "Music", Key: { "Artist":"No One You Know", "SongTitle":"Call Me Today" }, UpdateExpression: "SET Plays = :val", ExpressionAttributeValues: { ":val": 0 }, ReturnValues: "UPDATED_NEW" }
ReturnValues 参数设置为 UPDATED_NEW,这将返回已更新的任何属性的新值。在此示例中,它返回 0(零)。
当某人播放此歌曲时,可以使用如下 UpdateItem 操做来将 Plays 增长 1:
{ TableName: "Music", Key: { "Artist":"No One You Know", "SongTitle":"Call Me Today" }, UpdateExpression: "SET Plays = Plays + :incr", ExpressionAttributeValues: { ":incr": 1 }, ReturnValues: "UPDATED_NEW" }
UpdateItem 一次只能更新一个项目
UpdateItem 更新更新整个项目而不是只修改特色的值
UpdateItem 支持条件写入
这一节咱们介绍了DynamoDB 项目的更新操做,下一节咱们将介绍项目的删除操做(索引的查询又要延后了。。