上一節我們介紹了DynamoDB 表的操作,這一節將介紹專案的新增 修改 獲取 刪除操作。
建立專案
Amazon DynamoDB 提供了 PutItem 和 BatchWriteItem 兩種方式寫入資料
新增單個專案
在 Amazon DynamoDB 中,使用 PutItem 操作向表新增專案:
{
TableName: "Music",
Item: {
"Artist":"No One You Know",
"SongTitle":"Call Me Today",
"AlbumTitle":"Somewhat Famous",
"Year": 2015,
"Price": 2.14,
"Genre": "Country",
"Tags": {
"Composers": [
"Smith",
"Jones",
"Davis"
],
"LengthInSeconds": 214
}
}
}
此表的主鍵包含 Artist 和 SongTitle。您必須為這些屬性指定值。
以下是要了解的有關此 PutItem 示例的幾個關鍵事項:
-
DynamoDB 使用 JSON 提供對文件的本機支援。這使得 DynamoDB 非常適合儲存半結構化資料,例如 Tags。您也可以從 JSON 文件中檢索和運算元據。
-
除了主鍵(Artist 和 SongTitle),Music 表沒有預定義的屬性。
-
大多數 SQL 資料庫是面向事務的。當您發出 INSERT 語句時,資料修改不是永久性的,直至您發出 COMMIT 語句。利用 Amazon DynamoDB,當 DynamoDB 通過 HTTP 200 狀態程式碼 (OK) 進行回覆時,PutItem 操作的效果是永久性的。
Python Example
boto3
# ...
table = db3.Table(`Music`)
table.put_item(
Item = {
"Artist": "No One You Know",
"SongTitle": "My Dog Spot",
"AlbumTitle": "Hey Now",
"Price": Decimal(`1.98`),
"Genre": "Country",
"CriticRating": Decimal(`8.4`)
}
)
Out[98]:
{`ResponseMetadata`: {`HTTPHeaders`: {`content-length`: `2`,
`content-type`: `application/x-amz-json-1.0`,
`server`: `Jetty(8.1.12.v20130726)`,
`x-amz-crc32`: `2745614147`,
`x-amzn-requestid`: `c7c6be12-9752-403f-97b1-a9ac451a0a98`},
`HTTPStatusCode`: 200,
`RequestId`: `c7c6be12-9752-403f-97b1-a9ac451a0a98`,
`RetryAttempts`: 0}}
table.put_item(
Item = {
"Artist": "No One You Know",
"SongTitle": "Somewhere Down The Road",
"AlbumTitle":"Somewhat Famous",
"Genre": "Country",
"CriticRating": Decimal(`8.4`),
"Year": 1984
}
)
table.put_item(
Item = {
"Artist": "The Acme Band",
"SongTitle": "Still In Love",
"AlbumTitle":"The Buck Starts Here",
"Price": Decimal(`2.47`),
"Genre": "Rock",
"PromotionInfo": {
"RadioStationsPlaying":[
"KHCR", "KBQX", "WTNR", "WJJH"
],
"TourDates": {
"Seattle": "20150625",
"Cleveland": "20150630"
},
"Rotation": "Heavy"
}
}
)
table.put_item(
Item = {
"Artist": "The Acme Band",
"SongTitle": "Look Out, World",
"AlbumTitle":"The Buck Starts Here",
"Price": Decimal(`0.99`),
"Genre": "Rock"
}
)
Note
-
PutItem 是覆蓋操作,如果主鍵相同,第二次執行將覆蓋掉之前的資料
-
除了 PutItem 之外,Amazon DynamoDB 還支援同時寫入多個(最多25個)專案的 BatchWriteItem 操作。
新增多個專案
Python Example
boto3
# ...
table = db3.Table(`Music`)
with table.batch_writer() as batch:
batch.put_item(
Item = {
"Artist": "The Acme Band",
"SongTitle": "Look Out, World",
"AlbumTitle":"The Buck Starts Here",
"Price": Decimal(`0.99`),
"Genre": "Rock"
}
)
batch.put_item(
Item = {
"Artist": "The Acme Band 0",
"SongTitle": "Look Out, World",
"AlbumTitle":"The Buck Starts Here",
"Price": Decimal(`1.99`),
"Genre": "Rock"
}
)
batch.put_item(
Item = {
"Artist": "The Acme Band 1",
"SongTitle": "Look Out, World",
"AlbumTitle":"The Buck Starts Here",
"Price": Decimal(`2.99`),
"Genre": "Rock"
}
)
batch.put_item(
Item = {
"Artist": "The Acme Band 1",
"SongTitle": "Look Out, World",
"AlbumTitle":"The Buck Starts Here",
}
)
BatchWriteItem 使用 overwrite_by_pkeys=[`partition_key`,`sort_key`] 引數去除專案中重複的部分。
with table.batch_writer(overwrite_by_pkeys=[`partition_key`, `sort_key`]) as batch:
batch.put_item(
Item={
`partition_key`: `p1`,
`sort_key`: `s1`,
`other`: `111`,
}
)
batch.put_item(
Item={
`partition_key`: `p1`,
`sort_key`: `s1`,
`other`: `222`,
}
)
去重後,等同於:
with table.batch_writer(overwrite_by_pkeys=[`partition_key`, `sort_key`]) as batch:
batch.put_item(
Item={
`partition_key`: `p1`,
`sort_key`: `s1`,
`other`: `222`,
}
)
讀取資料
利用 SQL,我們可以使用 SELECT 語句從表中檢索一個或多個行。可使用 WHERE 子句來確定返回給您的資料
DynamoDB 提供以下操作來讀取資料:
-
GetItem – 從表中檢索單個專案。這是讀取單個專案的最高效方式,因為它將提供對專案的物理位置的直接訪問。(DynamoDB 還提供 BatchGetItem 操作,在單個操作中執行最多 100 個 GetItem 呼叫。)
-
Query – 檢索具有特定分割槽鍵的所有專案。在這些專案中,您可以將條件應用於排序鍵並僅檢索一部分資料。Query提供對儲存資料的分割槽的快速高效的訪問。
-
Scan – 檢索指定表中的所有專案。
Note
利用關聯式資料庫,您可以使用 SELECT 語句聯接多個表中的資料並返回結果。聯接是關係模型的基礎。要確保聯接高效執行,應持續優化資料庫及其應用程式的效能。
DynamoDB 是一個非關係 NoSQL 資料庫且不支援表聯接。相反,應用程式一次從一個表中讀取資料。
使用專案的主鍵讀取專案
DynamoDB 提供 GetItem 操作來按專案的主鍵檢索專案。
預設情況下,GetItem 將返回整個專案及其所有屬性。
{
TableName: "Music",
Key: {
"Artist": "No One You Know",
"SongTitle": "Call Me Today"
}
}
可以新增 ProjectionExpression 引數以僅返回一些屬性:
{
TableName: "Music",
Key: {
"Artist": "No One You Know",
"SongTitle": "Call Me Today"
},
"ProjectionExpression": "AlbumTitle, Price"
}
-
DynamoDB GetItem 操作非常高效:此操作使用主鍵值確定相關專案的準確儲存位置,並直接此位置檢索該專案。
-
SQL SELECT 語句支援多種查詢和表掃描。DynamoDB 通過其 Query 和 Scan 操作提供相似功能,如查詢表和掃描表中所述。
-
SQL SELECT 語句可執行表聯接,這允許您同時從多個表中檢索資料。DynamoDB 是一個非關聯式資料庫。因此,它不支援表聯接。
Query 和 Scan 操作將在之後的章節詳細介紹。
Python Example
boto3
# ...
table = db3.Table(`Music`)
response = table.get_item(
Key={
"Artist": "The Acme Band",
"SongTitle": "Still In Love"
}
)
item = response[`Item`]
print(item)
# output
{
"Artist": "The Acme Band",
"SongTitle": "Still In Love",
"AlbumTitle":"The Buck Starts Here",
"Price": Decimal(`2.47`),
"Genre": "Rock",
"PromotionInfo": {
"RadioStationsPlaying":[
"KHCR", "KBQX", "WTNR", "WJJH"
],
"TourDates": {
"Seattle": "20150625",
"Cleveland": "20150630"
},
"Rotation": "Heavy"
}
}
response = table.get_item(
Key={
"Artist": "The Acme Band",
"SongTitle": "Still In Love"
},
ProjectionExpression = "AlbumTitle, Price"
)
item = response[`Item`]
print(item)
{
`AlbumTitle`: u`The Buck Starts Here`,
`Price`: Decimal(`2.47`)
}
更新
SQL 語言提供用於修改資料的 UPDATE 語句。DynamoDB 使用 UpdateItem 操作完成類似的任務。
在 DynamoDB 中,可使用 UpdateItem 操作修改單個專案。(如果要修改多個專案,則必須使用多個 UpdateItem 操作。)
示例如下:
{
TableName: "Music",
Key: {
"Artist":"No One You Know",
"SongTitle":"Call Me Today"
},
UpdateExpression: "SET RecordLabel = :label",
ExpressionAttributeValues: {
":label": "Global Records"
}
}
-
必須指定要修改的專案的 Key 屬性和一個用於指定屬性值的 UpdateExpression。
-
UpdateItem 替換整個專案,而不是替換單個屬性。
-
UpdateItem 的行為與“upsert”操作的行為類似:如果專案位於表中,則更新專案,否則新增(插入)新專案。
-
UpdateItem 支援條件寫入,在此情況下,操作僅在特定 ConditionExpression 的計算結果為 true 時成功完成
{
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 的屬性(可遞增或遞減)。
以下是一個 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"
}
Python Example
boto3
使用 UpdateItem 操作修改單個專案
import boto3
import json
import decimal
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, decimal.Decimal):
if o % 1 > 0:
return float(o)
else:
return int(o)
return super(DecimalEncoder, self).default(o)
db3 = boto3.resource(`dynamodb`, region_name=`us-west-2`, endpoint_url="http://localhost:8000")
table = db3.Table(`Music`)
response = table.update_item(
Key={
"Artist":"No One You Know",
"SongTitle":"Call Me Today"
},
UpdateExpression="SET RecordLabel = :label",
ExpressionAttributeValues={
":label": "Global Records"
},
ReturnValues="UPDATED_NEW"
)
print(json.dumps(response, indent=4, cls=DecimalEncoder))
UpdateItem 條件寫入 價格大於或等於 2.00 UpdateItem 執行更新
table = db3.Table(`Music`)
response = table.update_item(
Key={
"Artist":"No One You Know",
"SongTitle":"Call Me Today"
},
UpdateExpression="SET RecordLabel = :label",
ConditionExpression="Price >= :p",
ExpressionAttributeValues={
":label": "Global Records",
":p": 2.00
},
ReturnValues="UPDATED_NEW"
)
UpdateItem 操作的示例,它初始化一個新屬性 (Plays) 來跟蹤歌曲的已播放次數
table = db3.Table(`Music`)
response = table.update_item(
Key={
"Artist":"No One You Know",
"SongTitle":"Call Me Today"
},
UpdateExpression="SET Plays = :val",
ExpressionAttributeValues={
":val": 0
},
ReturnValues="UPDATED_NEW"
)
使用 UpdateItem 操作來將 Plays 增加 1
table = db3.Table(`Music`)
response = table.update_item(
Key={
"Artist":"No One You Know",
"SongTitle":"Call Me Today"
},
UpdateExpression="SET Plays = Plays + :incr",
ExpressionAttributeValues={
":incr": 1
},
ReturnValues="UPDATED_NEW"
)
刪除專案
在 SQL 中,DELETE 語句從表中刪除一個或多個行。DynamoDB 使用 DeleteItem 操作一次刪除一個專案。
在 DynamoDB 中,可使用 DeleteItem 操作從表中刪除資料(一次刪除一個專案)。您必須指定專案的主鍵值。示例如下:
{
TableName: "Music",
Key: {
Artist: "The Acme Band",
SongTitle: "Look Out, World"
}
}
Note
除了 DeleteItem 之外,Amazon DynamoDB 還支援同時刪除多個專案的 BatchWriteItem 操作。
DeleteItem 支援條件寫入,在此情況下,操作僅在特定 ConditionExpression 的計算結果為 true 時成功完成。例如,以下 DeleteItem 操作僅在專案具有 RecordLabel 屬性時刪除專案:
{
TableName: "Music",
Key: {
Artist: "The Acme Band",
SongTitle: "Look Out, World"
},
ConditionExpression: "attribute_exists(RecordLabel)"
}
Python Example
boto3
table = db3.Table(`Music`)
table.delete_item(
Key={
`AlbumTitle`: `Hey Now`
`Artist`: `No One You Know`
}
)
這一節我們介紹了專案的基本操作(CRUD),下一節將介紹索引的建立和管理。