Serverless 入門(七)- DynamoDB 數(shù)據(jù)庫(中)

上一篇 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)文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容