Day 28 - AWS Lambda 結合 Dynamodb 介紹了如何利用 AWS Lambda 來讀取 Dynamodb,只是查詢的條件太過單調,只能用事先定義好的主鍵,在這裡展示兩種常見的用法:
指定 Dynamodb 特定屬性查詢
如果要在 Dynamodb 的資料表中基於非主鍵屬性來查詢資料的話,需要建立二級索引。通過二級索引,使用者可以對表主鍵之外的屬性執行查詢。 利用二級索引,除了可對主鍵進行查詢外,還可使用替代鍵查詢表中的數據。除了替代鍵屬性和主鍵屬性(分區鍵和排序鍵)之外,二級索引還包含其他表屬性的子集。當建立索引時,可指定哪些屬性將從基表複製或投影到索引。DynamoDB 至少會將鍵屬性從基表投影到索引中。二級索引包含以下內容:
二級索引可以是以下其中一種類型:
DynamoDB 中的每個表最多可具有 20 個全域二級索引(預設限制)和 5 個本地二級索引。
打開 DynamoDB 控制台,點擊左手邊主要功能列中的 資料表,選取事先建立好的資料表 fishInfoTbl ,點擊 索引 頁籤,接著點擊 建立索引 按鈕。
圖 1、建立 DynamoDB 資料表的二級索引
進入建立全域輔助索引配置畫面,輸入分區索引鍵 Mark ,因為我們要查詢的分區索引鍵並非所有資料表的分區鍵,所以這是屬於全域二級索引,設定完畢後,點擊 建立索引 按鈕,需要等待 5 分鐘左右才會完成建立索引,索引需要額外收費。
圖 2、建立 DynamoDB 資料表的全域二級索引
在 AWS Lambda 進行非主鍵的查詢,進入 AWS Lambda 控制台,找到 Day 28 - Amazon Lambda 結合 Dynamodb 所建立的 Lambda 函式 getDataFromDynamoDB,如下圖所示。
圖 3、進入 AWS Lambda 函式
將以下代碼輸入 lambda_function.py ,主要是使用 boto3 包指定要存取 dynamodb 資源,而指定要查詢的對象是 fishInfoTbl 資料表中 Mark='1' 的結果,在這裡提醒一個注意事項, AWS Lambda 與 DynamoDB 都是區域型的 AWS 服務,所以要先確認兩者是在同一個地區 (Region),不然會運行會出錯。
lambda_function.py
import json
import boto3
from boto3.dynamodb.conditions import Key
dynamodb = boto3.resource('dynamodb')
def lambda_handler(event, context):
qry = '1'
table = dynamodb.Table('fishInfoTbl')
data = table.query(
IndexName='Mark-index',
KeyConditionExpression = Key('Mark').eq(qry)
)
print('data=',data['Items'][0])
response = {
'statusCode': 200,
'body': json.dumps(data['Items'][0]),
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
}
return response
運行 AWS Lambda 函式結果如下圖所示,記得在撰寫完代碼後要先 Deploy ,在透過 Test 來運行。
圖 4、運行 AWS Lambda 函式
傳入參數給 AWS Lambda
傳入參數的部分,可以重新設定測試事件,在 Test 按鈕旁有一個倒三角形按鈕,按下該按鈕後,點擊 Configure test event ,可以重新組態 test 事件內容,如下圖所示。
圖 5、重新設定測試事件
下圖中可以 JSON 格式指定要傳入的參數。
圖 6、指定測試事件中的參數
設定完畢後,可以透過呼叫函式 lambda_handler 中的 event 參數取得 test 事件中所傳進來的參數內容。
lambda_function.py
import json
import boto3
from boto3.dynamodb.conditions import Key
dynamodb = boto3.resource('dynamodb')
def lambda_handler(event, context):
qry = event['Mark'] # 只需修改此行就可接收參數
table = dynamodb.Table('fishInfoTbl')
data = table.query(
IndexName='Mark-index',
KeyConditionExpression = Key('Mark').eq(qry)
)
print('data=',data['Items'][0])
response = {
'statusCode': 200,
'body': json.dumps(data['Items'][0]),
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
}
return response
圖 7、AWS Lambda 函式取得參數的運算結果