上一節介紹了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 項目的更新操做,下一節咱們將介紹項目的刪除操做(索引的查詢又要延後了。。