上一篇 Serverless 入門(六)- DynamoDB 數(shù)據(jù)庫 介紹了為數(shù)據(jù)庫創(chuàng)建一個表的整個過程,現(xiàn)在我們就來介紹如何更全面的操作數(shù)據(jù)庫,包含:刪除表、查詢記錄、修改記錄,新增記錄,刪除記錄。
1. 刪除數(shù)據(jù)表
export const dropTable = {
TableName: 'Movies',
};
import { createTable, dropTable } from "./models/movie";
export const drop: APIGatewayProxyHandler = async (event) => {
const dynamodb = getDynamoClient(event);
try {
const { TableDescription = {} } = await dynamodb.deleteTable(dropTable).promise();
return {
body: JSON.stringify({
creationDateTime: TableDescription.CreationDateTime,
tableStatus: TableDescription.TableStatus,
tableName: TableDescription.TableName,
message: 'Table drop successfully!',
}),
statusCode: 200,
};
} catch (e) {
return {
body: JSON.stringify(e),
statusCode: 500,
};
}
};
打開 serverless.yml 文件,在 createTable 同級下,新增如下配置:
dropTable:
handler: src/table.drop
events:
- http:
method: get
path: drop
雖然我們的服務(wù)命令中 「sls offline --useSeparateProcesses」 使用了熱加載,不針對 serverless.yml 配置,所以得重新執(zhí)行一次上述命令。
2. 創(chuàng)建數(shù)據(jù)表
- 編寫如下建表描述語句:AttributeDefinitions 表示定義「字段」,KeySchema 表示定義「主鍵」, ProvisionedThroughput 表示定義「吞吐量」
export const createTable = {
AttributeDefinitions: [
// 主鍵數(shù)據(jù)類型
{ AttributeName: 'year', AttributeType: 'N' }, // N Number
{ AttributeName: 'title', AttributeType: 'S' }, // S String
],
KeySchema: [
// 主鍵
{ AttributeName: 'year', KeyType: 'HASH' }, // Partition key 分區(qū)鍵
{ AttributeName: 'title', KeyType: 'RANGE' }, // Sort key 排序鍵
],
ProvisionedThroughput: {
// DynamoDB 預(yù)分配的吞吐量
ReadCapacityUnits: 20,
WriteCapacityUnits: 20,
},
TableName: 'Movies', // 表名
};
- 建表方法,代碼如下:
export const create: APIGatewayProxyHandler = async event => {
const dynamodb = dynamoDBClient(event);
try {
const { TableDescription = {} } = await dynamodb.createTable(createTable).promise();
return {
body: JSON.stringify({
creationDateTime: TableDescription.CreationDateTime,
tableStatus: TableDescription.TableStatus,
tableName: TableDescription.TableName,
message: `Create table successfully!`,
}),
statusCode: 200,
};
} catch (e) {
return {
body: JSON.stringify(e),
statusCode: 500,
};
}
};
- 配置
serverless.yml函數(shù)
# 創(chuàng)建表
createTable:
# table.ts 文件放到 src 里了,所以要加 src
handler: src/table.create
events:
- http:
method: get
path: create
- 執(zhí)行成功后,會有如下提示:
{
creationDateTime: "2019-03-21T09:26:10.349Z",
tableStatus: "ACTIVE",
tableName: "Movies",
message: "Table create successfully!"
}
3. 新增記錄
新增表記錄時,就有一點(diǎn)不同了,我們換成使用dynamoDBDocumentClient來操作DynamoDB 了。
export const saveData: APIGatewayProxyHandler = async event => {
const params = {
TableName: 'Movies',
Item: {
year: 2015,
title: 'The Big New Movie',
info: {
plot: 'Nothing happens at all.',
rating: 0,
},
},
};
try {
const dynamodbDoc = dynamoDBDocumentClient(event);
const result = await dynamodbDoc.put(params).promise();
return {
body: JSON.stringify({ ...result, message: `Table save data successfully!` }),
statusCode: 200,
};
} catch (e) {
return getExceptionBody(e);
}
};
dynamoDBDocumentClient 的代碼只是在 DynamoDB里的對象里實(shí)例化一個 DocumentClient 對象,如下所示:
export const dynamoDBDocumentClient = (event, port = 8000, region = 'localhost') => {
if ('isOffline' in event && event.isOffline) {
return new DynamoDB.DocumentClient({ endpoint: `http://localhost:${port}`, region });
}
return new DynamoDB.DocumentClient();
};
4. 查詢記錄
在 DynamoDB 里查詢記錄可以簡單分為如下三種:
- get 獲取某一條記錄
const params = { TableName: 'Movies', Key: { year: 2013, title: 'Rush' } };
const result = await dynamodbDoc.get(params).promise();
- query 獲取指定條件的記錄
const params = {
TableName: 'Movies',
KeyConditionExpression: '#year=:yyyy',
ExpressionAttributeNames: { '#year': 'year' },
ExpressionAttributeValues: { ':yyyy': 1993 },
};
const result = await dynamodbDoc.query(params).promise();
- scan 獲取大量的記錄
const params = {
TableName: 'Movies',
// 只查詢?nèi)缦?3 個「字段」
ProjectionExpression: '#year, title, info.rating',
// 過慮器表達(dá)式
FilterExpression: '#year between :start and :end',
ExpressionAttributeNames: { '#year': 'year' },
ExpressionAttributeValues: { ':start': 1993, ':end': 2019 },
};
const result = await dynamodbDoc.scan(params).promise();
5. 修改記錄
先指定表名、主鍵名,然后配置更新表達(dá)式及對應(yīng)的值,如代碼所示:
const params = {
TableName: 'Movies',
Key: { year: 2015, title: 'The Big New Movie' },
UpdateExpression: 'set info.rating=:r, info.plot=:p, info.actors=:a',
ExpressionAttributeValues: {
':r': 5.5,
':p': 'Everything happens all at once.',
':a': ['Larry', 'Moe', 'Curly'],
},
// ReturnValues 有如下幾種:NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW
ReturnValues: 'UPDATED_NEW',
};
const result = await dynamodbDoc.update(params).promise();
這種用表達(dá)式的方式修改數(shù)據(jù),有效的解決了 SQL 注入的問題,安心!
6. 刪除記錄
刪除記錄跟上面的代碼與套路相似,我就直接列出代碼片段:
const params = {
TableName: 'Movies',
Key: { year: 2015, title: 'The Big New Movie' },
ConditionExpression: 'info.rating >= :value',
ExpressionAttributeValues: { ':value': 5.0 },
};
const result = await dynamodbDoc.delete(params).promise();
7. 項(xiàng)目源代碼
由于篇幅原因,上面的代碼我只貼出了片段,下面鏈接是代碼詳情:
https://github.com/Kennytian/learning-serverless
8. 好消息
- 上篇文章里介紹的「Dynamon」工具,打開大數(shù)量的表時會 crash。所以我又找到了另一位作者開發(fā)的版本,其兼容性與 UI 美觀程序會更勝一籌,項(xiàng)目地址 https://github.com/deptno/dynamon ,UI 如圖所示:
Dynamon GUI Client for macOS
相關(guān)文章
- Serverless 入門(一) - 創(chuàng)建 IAM http://m.itdecent.cn/p/9fb731a799e2
- Serverless 入門(二) - HelloWord http://m.itdecent.cn/p/ddf2ffda5f63
- Serverless 入門(三)- 初始項(xiàng)目解讀 http://m.itdecent.cn/p/8baba2a8fe9f
- Serverless 入門(四)- 如何調(diào)試 http://m.itdecent.cn/p/58d30915de8a
- Serverless 入門(五)- 常用命令 http://m.itdecent.cn/p/28f001ea9d9d
- Serverless 入門(六)- DynamoDB 數(shù)據(jù)庫(上) http://m.itdecent.cn/p/c313b61d1cbf
- Serverless 入門(七)- DynamoDB 數(shù)據(jù)庫(中) http://m.itdecent.cn/p/05e7f4ccd6fe
- Serverless 入門(八)- DynamoDB 數(shù)據(jù)庫(下) http://m.itdecent.cn/p/0f9f1561ec46
- Serverless 入門(九)- 權(quán)限 http://m.itdecent.cn/p/97228749d761
