

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 建立應用程式以執行排定的資料庫維護
<a name="scheduled-task-app"></a>

您可以使用 AWS Lambda 取代排程程序，例如自動化系統備份、檔案轉換和維護任務。在此範例中，您會建立一個無伺服器應用程式，用於透過刪除舊項目，對 DynamoDB 資料表執行定期的排定維護。該應用程式使用 EventBridge 排程器，對 Cron 排程調用 Lambda 函數。調用時，函數會查詢資料表中是否有超過一年的項目，並刪除它們。函數會在 CloudWatch Logs 中記錄刪除的每個項目。

若要實作此範例，首先需要建立 DynamoDB 資料表，並將其填入一些測試資料，以供函數查詢。然後，建立具有 EventBridge 排程器觸發條件的 Python Lambda 函數，並為該函數建立 IAM 執行角色，讓其能夠從資料表讀取和刪除項目。

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/ExampleApps/cron_app.png)


**提示**  
如果您是 Lambda 的新手，建議您在建立此範例應用程式之前完成教學課程「[建立第一個 Lambda 函數](getting-started.md)」。

您可以使用 建立和設定資源，以手動部署您的應用程式 AWS 管理主控台。您也可以使用 AWS Serverless Application Model (AWS SAM) 來部署應用程式。 AWS SAM 是基礎設施即程式碼 (IaC) 工具。藉助 IaC，您無需手動建立資源，而是在程式碼中定義資源，然後便可自動部署資源。

如果您想要在部署此範例應用程式之前，進一步了解如何將 Lambda 與 IaC 搭配使用，請參閱[將 Lambda 搭配基礎設施即程式碼 (IaC)](foundation-iac.md)。

## 先決條件
<a name="scheduled-task-app-prereqs"></a>

在建立範例應用程式之前，請確保已安裝必要的命令列工具和程式。
+ **Python**

  為向用於測試應用程式的 DynamoDB 資料表填入資料，此範例使用 Python 指令碼和 CSV 檔案。請確定您的機器已安裝 Python 3.8 版或更新版本。
+ **AWS SAM CLI**

  如果您想要使用 建立 DynamoDB 資料表並部署範例應用程式 AWS SAM，則需要安裝 AWS SAM CLI。如需了解如何安裝，請參閱《AWS SAM 使用者指南》**中的[安裝指示](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html)。
+ **AWS CLI**

  若要使用提供的 Python 指令碼填入測試資料表，則需要安裝並設定 AWS CLI。這是因為指令碼使用 適用於 Python (Boto3) 的 AWS SDK，需要存取您的 AWS Identity and Access Management (IAM) 登入資料。您也需要 AWS CLI 安裝 ，才能使用 來部署資源 AWS SAM。若要安裝 CLI，請參閱《AWS Command Line Interface 使用者指南》**中的[安裝指示](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
+ **Docker**

  若要使用 部署應用程式 AWS SAM，您的建置機器也必須安裝 Docker。請遵循 Docker 文件網站上 [Install Docker Engine](https://docs.docker.com/engine/install/) 一節的指示。

## 下載範例應用程式檔案
<a name="scheduled-task-app-download"></a>

若要建立範例資料庫和排定維護應用程式，您需要在專案目錄中建立下列檔案：

**範例資料庫檔案**
+ `template.yaml` - 可用來建立 DynamoDB 資料表的 AWS SAM 範本
+ `sample_data.csv`：CSV 檔案，其中包含要載入資料表的範例資料
+ `load_sample_data.py`：Python 指令碼，用於將 CSV 檔案中的資料寫入資料表

**排定維護應用程式檔案**
+ `lambda_function.py`：執行資料庫維護之 Lambda 函數的 Python 函數程式碼
+ `requirements.txt`：資訊清單檔案，用於定義 Python 函數程式碼所需的相依項
+ `template.yaml` - 可用來部署應用程式的 AWS SAM 範本

**測試檔案**
+ `test_app.py`：Python 指令碼，用於掃描資料表，以確認函數的成功運作，並輸出已存在超過一年的所有記錄

展開以下區段以檢視程式碼，並進一步了解每個檔案在建立和測試應用程式過程中的作用。若要在本機機器上建立這些檔案，請複製並貼上下面的程式碼。

### AWS SAM 範本 （範例 DynamoDB 資料表）
<a name="scheduled-task-app-table-yaml"></a>

複製以下程式碼並貼到名稱為 `template.yaml` 的檔案中。

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM Template for DynamoDB Table with Order_number as Partition Key and Date as Sort Key

Resources:
  MyDynamoDBTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      TableName: MyOrderTable
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: Order_number
          AttributeType: S
        - AttributeName: Date
          AttributeType: S
      KeySchema:
        - AttributeName: Order_number
          KeyType: HASH
        - AttributeName: Date
          KeyType: RANGE
      SSESpecification:
        SSEEnabled: true
      GlobalSecondaryIndexes:
        - IndexName: Date-index
          KeySchema:
            - AttributeName: Date
              KeyType: HASH
          Projection:
            ProjectionType: ALL
      PointInTimeRecoverySpecification:
        PointInTimeRecoveryEnabled: true

Outputs:
  TableName:
    Description: DynamoDB Table Name
    Value: !Ref MyDynamoDBTable
  TableArn:
    Description: DynamoDB Table ARN
    Value: !GetAtt MyDynamoDBTable.Arn
```

**注意**  
AWS SAM 範本使用 的標準命名慣例`template.yaml`。此範例有兩個範本檔案：一個用於建立範例資料庫，另一個用於建立應用程式本身。將它們儲存在專案資料夾的單獨子目錄中。

此 AWS SAM 範本會定義您為測試應用程式所建立的 DynamoDB 資料表資源。該資料表的主索引鍵為 `Order_number`，排序索引鍵為 `Date`。為了讓該 Lambda 函數直接依日期尋找項目，我們還定義了名為 `Date-index` 的[全域次要索引](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html)。

若要進一步了解如何使用 `AWS::DynamoDB::Table` 資源建立和設定 DynamoDB 資料表，請參閱《AWS CloudFormation 使用者指南》**中的 [AWS::DynamoDB::Table](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html) 一節。

### 範例資料庫資料檔案
<a name="scheduled-task-app-csv-file"></a>

複製以下程式碼並貼到名稱為 `sample_data.csv` 的檔案中。

```
Date,Order_number,CustomerName,ProductID,Quantity,TotalAmount
2023-09-01,ORD001,Alejandro Rosalez,PROD123,2,199.98
2023-09-01,ORD002,Akua Mansa,PROD456,1,49.99
2023-09-02,ORD003,Ana Carolina Silva,PROD789,3,149.97
2023-09-03,ORD004,Arnav Desai,PROD123,1,99.99
2023-10-01,ORD005,Carlos Salazar,PROD456,2,99.98
2023-10-02,ORD006,Diego Ramirez,PROD789,1,49.99
2023-10-03,ORD007,Efua Owusu,PROD123,4,399.96
2023-10-04,ORD008,John Stiles,PROD456,2,99.98
2023-10-05,ORD009,Jorge Souza,PROD789,3,149.97
2023-10-06,ORD010,Kwaku Mensah,PROD123,1,99.99
2023-11-01,ORD011,Li Juan,PROD456,5,249.95
2023-11-02,ORD012,Marcia Oliveria,PROD789,2,99.98
2023-11-03,ORD013,Maria Garcia,PROD123,3,299.97
2023-11-04,ORD014,Martha Rivera,PROD456,1,49.99
2023-11-05,ORD015,Mary Major,PROD789,4,199.96
2023-12-01,ORD016,Mateo Jackson,PROD123,2,199.99
2023-12-02,ORD017,Nikki Wolf,PROD456,3,149.97
2023-12-03,ORD018,Pat Candella,PROD789,1,49.99
2023-12-04,ORD019,Paulo Santos,PROD123,5,499.95
2023-12-05,ORD020,Richard Roe,PROD456,2,99.98
2024-01-01,ORD021,Saanvi Sarkar,PROD789,3,149.97
2024-01-02,ORD022,Shirley Rodriguez,PROD123,1,99.99
2024-01-03,ORD023,Sofia Martinez,PROD456,4,199.96
2024-01-04,ORD024,Terry Whitlock,PROD789,2,99.98
2024-01-05,ORD025,Wang Xiulan,PROD123,3,299.97
```

此檔案包含一些範例測試資料，為標準逗號分隔值 (CSV) 格式，用於填入 DynamoDB 資料表。

### 用於載入範例資料的 Python 指令碼
<a name="scheduled-task-app-load-script"></a>

複製以下程式碼並貼到名稱為 `load_sample_data.py` 的檔案中。

```
import boto3
import csv
from decimal import Decimal

# Initialize the DynamoDB client
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('MyOrderTable') 
print("DDB client initialized.")

def load_data_from_csv(filename):
    with open(filename, 'r') as file:
        csv_reader = csv.DictReader(file)
        for row in csv_reader:
            item = {
                'Order_number': row['Order_number'],
                'Date': row['Date'],
                'CustomerName': row['CustomerName'],
                'ProductID': row['ProductID'],
                'Quantity': int(row['Quantity']),
                'TotalAmount': Decimal(str(row['TotalAmount']))
            }
            table.put_item(Item=item)
            print(f"Added item: {item['Order_number']} - {item['Date']}")

if __name__ == "__main__":
    load_data_from_csv('sample_data.csv')
    print("Data loading completed.")
```

此 Python 指令碼會先使用 適用於 Python (Boto3) 的 AWS SDK 來建立 DynamoDB 資料表的連線。然後，它會逐一查看 CSV 檔案 example-data 中的每一列，從該列建立項目，並使用 boto3 SDK 將項目寫入 DynamoDB 資料表。

### Python 函數程式碼
<a name="scheduled-task-app-function-code"></a>

複製以下程式碼並貼到名稱為 `lambda_function.py` 的檔案中。

```
import boto3
from datetime import datetime, timedelta
from boto3.dynamodb.conditions import Key, Attr
import logging

logger = logging.getLogger()
logger.setLevel("INFO")

def lambda_handler(event, context):
    # Initialize the DynamoDB client
    dynamodb = boto3.resource('dynamodb')
    
    # Specify the table name
    table_name = 'MyOrderTable'
    table = dynamodb.Table(table_name)
    
    # Get today's date
    today = datetime.now()
    
    # Calculate the date one year ago
    one_year_ago = (today - timedelta(days=365)).strftime('%Y-%m-%d')
    
    # Scan the table using a global secondary index
    response = table.scan(
        IndexName='Date-index',
        FilterExpression='#date < :one_year_ago',
        ExpressionAttributeNames={
            '#date': 'Date'
        },
        ExpressionAttributeValues={
            ':one_year_ago': one_year_ago
        }
    )
    
     # Delete old items
    with table.batch_writer() as batch:
        for item in response['Items']:
            Order_number = item['Order_number']
            batch.delete_item(
                Key={
                    'Order_number': Order_number,
                    'Date': item['Date']
                }
            )
            logger.info(f'deleted order number {Order_number}')
    
    # Check if there are more items to scan
    while 'LastEvaluatedKey' in response:
        response = table.scan(
            IndexName='DateIndex',
            FilterExpression='#date < :one_year_ago',
            ExpressionAttributeNames={
                '#date': 'Date'
            },
            ExpressionAttributeValues={
                ':one_year_ago': one_year_ago
            },
            ExclusiveStartKey=response['LastEvaluatedKey']
        )
        
        # Delete old items
        with table.batch_writer() as batch:
            for item in response['Items']:
                batch.delete_item(
                    Key={
                        'Order_number': item['Order_number'],
                        'Date': item['Date']
                    }
                )
    
    return {
        'statusCode': 200,
        'body': 'Cleanup completed successfully'
    }
```

該 Python 函數的程式碼包含 Lambda 在調用該函數時執行的[處理常式](python-handler.md)函數 (`lambda_handler`)。

當 EventBridge 排程器調用函數時，它會使用 適用於 Python (Boto3) 的 AWS SDK 來建立 DynamoDB 資料表的連線，以執行排定的維護任務。然後，它會使用 Python 程式庫 `datetime` 來計算距離當日一年的日期，然後再掃描資料表中是否有早於此日期的項目並刪除它們。

請注意，DynamoDB 查詢和掃描操作的回應大小上限為 1 MB。如果回應大於 1 MB，DynamoDB 會對資料進行分頁，並在回應中傳回 `LastEvaluatedKey` 元素。為了確保函數處理資料表中的所有記錄，我們會檢查此索引鍵是否存在，然後繼續從上次評估的位置執行資料表掃描，直到掃描完整個資料表為止。

### `requirements.txt` 資訊清單檔案
<a name="scheduled-task-app-dependencies"></a>

複製以下程式碼並貼到名稱為 `requirements.txt` 的檔案中。

```
boto3
```

在此範例中，函數程式碼只包含一個不屬於標準 Python 程式庫的相依項，即函數用於掃描 DynamoDB 資料表和刪除項目的適用於 Python 的 SDK (Boto3)。

**注意**  
Lambda 執行時期包含適用於 Python 的 SDK (Boto3) 版本，因此程式碼無需將 Boto3 新增至函數的部署套件即可執行。不過，為了維持對函數相依項的完整控制，並避免版本不一致可能造成的問題，Python 的最佳實務是在函數的部署套件中包含所有函數相依項。如需進一步了解，請參閱[Python 中的執行期相依項](python-package.md#python-package-dependencies)。

### AWS SAM 範本 （排程維護應用程式）
<a name="scheduled-task-app-table-yaml"></a>

複製以下程式碼並貼到名稱為 `template.yaml` 的檔案中。

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM Template for Lambda function and EventBridge Scheduler rule

Resources:
  MyLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: ScheduledDBMaintenance
      CodeUri: ./
      Handler: lambda_function.lambda_handler
      Runtime: python3.11
      Architectures:
        - x86_64
      Events:
        ScheduleEvent:
          Type: ScheduleV2
          Properties:
            ScheduleExpression: cron(0 3 1 * ? *)
            Description: Run on the first day of every month at 03:00 AM
      Policies:
        - CloudWatchLogsFullAccess
        - Statement:
            - Effect: Allow
              Action:
                - dynamodb:Scan
                - dynamodb:BatchWriteItem
              Resource: !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/MyOrderTable'

  LambdaLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${MyLambdaFunction}
      RetentionInDays: 30

Outputs:
  LambdaFunctionName:
    Description: Lambda Function Name
    Value: !Ref MyLambdaFunction
  LambdaFunctionArn:
    Description: Lambda Function ARN
    Value: !GetAtt MyLambdaFunction.Arn
```

**注意**  
AWS SAM 範本使用 的標準命名慣例`template.yaml`。此範例有兩個範本檔案：一個用於建立範例資料庫，另一個用於建立應用程式本身。將它們儲存在專案資料夾的單獨子目錄中。

此 AWS SAM 範本會定義您應用程式的資源。我們使用 `AWS::Serverless::Function` 資源定義 Lambda 函數。EventBridge 排程器排程和調用 Lambda 函數的觸發條件乃使用類型為 `ScheduleV2` 之此資源的 `Events` 屬性建立。若要進一步了解如何在 AWS SAM 範本中定義 EventBridge 排程器排程，請參閱《 *AWS Serverless Application Model 開發人員指南*》中的 [ScheduleV2](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-schedulev2.html)。

除了 Lambda 函數和 EventBridge 排程器排程外，我們還需要為該函數定義一個 CloudWatch 日誌群組，以將已刪除項目的記錄傳送至其中。

### 測試指令碼
<a name="scheduled-task-app-test-script"></a>

複製以下程式碼並貼到名稱為 `test_app.py` 的檔案中。

```
import boto3
from datetime import datetime, timedelta
import json

# Initialize the DynamoDB client
dynamodb = boto3.resource('dynamodb')

# Specify your table name
table_name = 'YourTableName'
table = dynamodb.Table(table_name)

# Get the current date
current_date = datetime.now()

# Calculate the date one year ago
one_year_ago = current_date - timedelta(days=365)

# Convert the date to string format (assuming the date in DynamoDB is stored as a string)
one_year_ago_str = one_year_ago.strftime('%Y-%m-%d')

# Scan the table
response = table.scan(
    FilterExpression='#date < :one_year_ago',
    ExpressionAttributeNames={
        '#date': 'Date'
    },
    ExpressionAttributeValues={
        ':one_year_ago': one_year_ago_str
    }
)

# Process the results
old_records = response['Items']

# Continue scanning if we have more items (pagination)
while 'LastEvaluatedKey' in response:
    response = table.scan(
        FilterExpression='#date < :one_year_ago',
        ExpressionAttributeNames={
            '#date': 'Date'
        },
        ExpressionAttributeValues={
            ':one_year_ago': one_year_ago_str
        },
        ExclusiveStartKey=response['LastEvaluatedKey']
    )
    old_records.extend(response['Items'])

for record in old_records:
    print(json.dumps(record))

# The total number of old records should be zero.
print(f"Total number of old records: {len(old_records)}")
```

此測試指令碼使用 適用於 Python (Boto3) 的 AWS SDK 建立 DynamoDB 資料表的連線，並掃描超過一年的項目。為了讓您能夠確認該 Lambda 函數是否已成功執行，在測試結束時，該函數會列印資料表中存在時間超過一年之記錄的數目。如果 Lambda 函數成功執行，則資料表中的舊記錄數目應為零。

## 建立範例 DynamoDB 資料表並填入資料
<a name="scheduled-task-app-create-table"></a>

若要測試該排定維護應用程式，請先建立 DynamoDB 資料表，並填入一些範例資料。您可以使用 AWS 管理主控台 手動或使用 AWS SAM自動建立資料表。建議您使用 AWS SAM ，使用幾個 AWS CLI 命令快速建立和設定資料表。

------
#### [ Console ]

**若要建立 DynamoDB 資料表**

1. 開啟 DynamoDB 主控台的[資料表](https://console.aws.amazon.com/dynamodbv2/home#tables)頁面。

1. 選擇**建立資料表**。

1. 執行下列動作來建立資料表：

   1. 在**資料表詳細資訊**下，對於**資料表名稱**，輸入 **MyOrderTable**。

   1. 對於**分割區索引鍵**，輸入 **Order\$1number** 並保持類型設定為**字串**。

   1. 對於**排序索引鍵**，輸入 **Date** 並保持類型設定為**字串**。

   1. 將**資料表設定**保持為**預設設定**，然後選擇**建立資料表**。

1. 當資料表完成建立且其**狀態**顯示為**作用中**時，請執行下列動作來建立全域次要索引 (GSI)。該應用程式將使用此 GSI 直接依日期搜尋項目，以決定要刪除的項目。

   1. 從資料表清單中選擇 **MyOrderTable**。

   1. 選擇**索引**索引標籤。

   1. 在**全域次要索引**下，選擇**建立索引**。

   1. 在**索引詳細資訊**下，輸入 **Date** 作為**分割區索引鍵**，並保持**資料類型**設定為**字串**。

   1. 對於 **Index name** (索引名稱)，輸入 **Date-index**。

   1. 保持所有其他參數的預設設定，捲動至頁面底部，然後選擇**建立索引**。

------
#### [ AWS SAM ]

**若要建立 DynamoDB 資料表**

1. 導覽至儲存 DynamoDB 資料表 `template.yaml` 檔案的資料夾。請注意，此範例使用兩個 `template.yaml` 檔案。請確定它們儲存在不同的子資料夾中，而且您位於包含範本的資料夾中，這樣才能建立 DynamoDB 資料表。

1. 執行下列命令。

   ```
   sam build
   ```

   此命令會收集要部署之資源的建置成品，並將它們放置在適當的格式和位置以進行部署。

1. 執行以下命令，以建立 `template.yaml` 檔案中指定的 DynamoDB 資源。

   ```
   sam deploy --guided
   ```

   使用 `--guided`旗標表示 AWS SAM 會顯示提示，引導您完成部署程序。在此部署中，輸入 **cron-app-test-db** 的 `Stack name`，並使用 Enter 鍵接受所有其他選項的預設值。

   當 AWS SAM 完成建立 DynamoDB 資源時，您應該會看到下列訊息。

   ```
   Successfully created/updated stack - cron-app-test-db in us-west-2
   ```

1. 此外，您可以透過開啟 DynamoDB 主控台的[資料表](https://console.aws.amazon.com/dynamodbv2/home#tables)頁面，進一步確認該 DynamoDB 資料表已成功建立。您應該會看到名為 `MyOrderTable` 的資料表。

------

建立資料表之後，您接下來需要新增一些範例資料來測試應用程式。您先前下載的 CSV 檔案 `sample_data.csv` 包含一些範例項目，其中包括訂單編號、日期，以及客戶和訂單資訊。使用提供的 python 指令碼 `load_sample_data.py`，將這些資料新增至資料表。

**若要將範例資料新增至資料表**

1. 導覽至包含檔案 `sample_data.csv` 和 `load_sample_data.py` 的目錄。如果這兩個檔案位於不同的目錄中，請將它們移動至同一位置。

1. 透過執行以下命令，建立用於執行該指令碼的 Python 虛擬環境。建議您使用虛擬環境，因為在後續步驟中，您需要安裝 適用於 Python (Boto3) 的 AWS SDK。

   ```
   python -m venv venv
   ```

1. 執行以下命令以啟用該虛擬環境：

   ```
   source venv/bin/activate
   ```

1. 執行以下命令，在虛擬環境中安裝適用於 Python 的 SDK (Boto3)。該指令碼使用此程式庫連線到 DynamoDB 資料表和新增項目。

   ```
   pip install boto3
   ```

1. 執行以下命令，以執行指令碼來填入資料表。

   ```
   python load_sample_data.py
   ```

   如果指令碼執行成功，則它會在載入每個項目時將其列印到主控台並報告 `Data loading completed`。

1. 執行以下命令以停用該虛擬環境：

   ```
   deactivate
   ```

1. 您可以透過進行以下操作，以確認資料是否已載入 DynamoDB 資料表：

   1. 開啟 DynamoDB 主控台的[探索項目](https://console.aws.amazon.com/dynamodbv2/home#item-explorer)頁面，然後選擇相應資料表 (`MyOrderTable`)。

   1. 在**傳回的項目**窗格中，您應該會看到指令碼新增至資料表的 CSV 檔案中的 25 個項目。

## 建立排定維護應用程式
<a name="scheduled-task-app-create-app"></a>

您可以使用 AWS 管理主控台 或使用 逐步建立和部署此範例應用程式的資源 AWS SAM。在生產環境中，我們建議您使用 Infrustracture-as-Code (IaC) 工具 AWS SAM ，例如 ，在不使用手動程序的情況下重複部署無伺服器應用程式。

在此範例中，請依照主控台指示了解如何分別設定每個 AWS 資源，或依照 AWS SAM 指示使用 AWS CLI 命令快速部署應用程式。

------
#### [ Console ]

**使用 建立 函數 AWS 管理主控台**

首先，建立包含基本入門程式碼的函數。然後，您可以直接在 Lambda 程式碼編輯器中複製和貼上的程式碼，或以 `.zip` 套件的形式上傳程式碼，從而以自己的函數程式碼取代此程式碼。針對此任務，建議複製並貼上程式碼。

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇**建立函數**。

1. 選擇 **Author from scratch** (從頭開始撰寫)。

1. 在**基本資訊**下，請執行下列動作：

   1. 針對**函數名稱**，請輸入 `ScheduledDBMaintenance`。

   1. 針對**執行時期**，選擇最新的 Python 版本。

   1. 對於 **Architecture** (架構)，選擇 **x86\$164**。

1. 選擇**建立函數**。

1. 建立函數後，您可以使用提供的函數程式碼來設定函數。

   1. 在**程式碼來源**窗格中，以您先前儲存的 `lambda_function.py` 檔案中的 Python 函數程式碼取代 Lambda 建立的 Hello world 程式碼。

   1. 在 **DEPLOY** 區段中，選擇**部署**以更新函數的程式碼：  
![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

**若要設定函數記憶體和逾時 (主控台)**

1. 選取函數的**組態**索引標籤。

1. 在**一般組態**窗格中，選擇**編輯**。

1. 將**記憶體**設定為 256 MB，並將**逾時**設定為 15 秒。如果您處理的是具有許多記錄的大型資料表，例如生產環境中的資料表，那麼可以考慮將**逾時**設定為較大的數字。這可讓函數有更多時間掃描和清理資料庫。

1. 選擇**儲存**。

**若要設定日誌格式 (主控台)**

您可以設定 Lambda 函數，以非結構化文字或 JSON 格式輸出日誌。建議您使用 JSON 格式的日誌，這樣搜尋和篩選日誌資料可以更輕鬆。若要進一步了解 Lambda 日誌組態選項，請參閱[設定 Lambda 函數的進階日誌記錄控制項](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)。

1. 選取函數的**組態**索引標籤。

1. 選取**監控和操作工具**。

1. 在**日誌組態**窗格中，選擇**編輯**。

1. 針對**記錄組態**，選取 **JSON**。

1. 選擇**儲存**。

**若要設定 IAM 許可**

若要向該函數提供讀取和刪除 DynamoDB 項目所需的許可，您需要向該函數的[執行角色](lambda-intro-execution-role.md)新增政策，以定義必要的許可。

1. 開啟**組態**索引標籤，然後從左側導覽列中選擇**許可**。

1. 在**執行角色**下面，選擇角色名稱。

1. 在 IAM 主控台中，選擇**新增許可**，然後選擇**建立內嵌政策**。

1. 使用 JSON 編輯器並輸入以下政策：  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "dynamodb:Scan",
                   "dynamodb:DeleteItem",
                   "dynamodb:BatchWriteItem"
               ],
               "Resource": "arn:aws:dynamodb:*:*:table/MyOrderTable"
           }
       ]
   }
   ```

1. 將政策命名為 **DynamoDBCleanupPolicy**，然後建立它。

**若要將 EventBridge 排程器設定為觸發條件 (主控台)**

1. 開啟 [EventBridge 主控台](https://console.aws.amazon.com/events/home)。

1. 在左側導覽窗格中，選擇**排程器**區段下的**排程器**。

1. 選擇**建立排程**。

1. 執行下列操作以配置排程：

   1. 在**排程名稱**下，輸入排程的名稱 (例如 **DynamoDBCleanupSchedule**)。

   1. 在**排程模式**下，選擇**週期性排程**。

   1. 對於**排程類型**，保留預設設定**以 Cron 為基礎的排程**，然後輸入以下排程詳細資訊：
      + **分鐘**：**0**
      + **小時**：**3**
      + **月曆日**：**1**
      + **月**：**\$1**
      + **一週當中的天**：**?**
      + **年**：**\$1**

      評估時，此 Cron 表達式會在每個月第一天的上午 03:00 執行。

   1. 對於**彈性時段**，選擇**關閉**。

1. 選擇**下一步**。

1. 執行以下操作以設定 Lambda 函數的觸發條件：

   1. 在**目標詳細資訊**窗格中，將**目標 API** 設定為**範本目標**，然後選取 **AWS Lambda 調用**。

   1. 在**調用**下，從下拉式清單中選取 Lambda 函數 (`ScheduledDBMaintenance`)。

   1. 讓**承載**保留空白，然後選擇**下一步**。

   1. 向下捲動至**許可**，然後選取**為此排程建立新角色**。當您使用主控台建立新的 EventBridge 排程器排程時，EventBridge 排程器會建立新的政策，其中包含該排程調用函數所需的必要許可。如需有關管理排程許可的詳細資訊，請參閱《EventBridge 排程器使用者指南》**中的 [Cron-based schedules](https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html#cron-based) 一節。

   1. 選擇**下一步**。

1. 檢閱設定，然後選擇**建立排程**，以完成排程和 Lambda 觸發條件的建立。

------
#### [ AWS SAM ]

**使用 部署應用程式 AWS SAM**

1. 導覽至儲存應用程式 `template.yaml` 檔案的資料夾。請注意，此範例使用兩個 `template.yaml` 檔案。請確定它們儲存在不同的子資料夾中，而且您位於包含範本的資料夾中，這樣才能建立應用程式。

1. 將您先前下載的檔案 `lambda_function.py` 和 `requirements.txt` 複製到相同的資料夾。 AWS SAM 範本中指定的程式碼位置為 `./`，表示目前位置。當您嘗試部署應用程式時， AWS SAM 將在此資料夾中搜尋 Lambda 函數程式碼。

1. 執行下列命令。

   ```
   sam build --use-container
   ```

   此命令會收集要部署之資源的建置成品，並將它們放置在適當的格式和位置以進行部署。指定 `--use-container` 選項可在類似 Lambda 的 Docker 容器中建置函數。之所以要使用它，是為了讓您不必在本機機器上安裝 Python 3.12，即可進行建置。

1. 執行以下命令，以建立 `template.yaml` 檔案中指定的 Lambda 和 EventBridge 排程器資源。

   ```
   sam deploy --guided
   ```

   使用 `--guided`旗標表示 AWS SAM 會顯示提示，引導您完成部署程序。在此部署中，輸入 **cron-maintenance-app** 的 `Stack name`，並使用 Enter 鍵接受所有其他選項的預設值。

   當 AWS SAM 完成建立 Lambda 和 EventBridge 排程器資源時，您應該會看到下列訊息。

   ```
   Successfully created/updated stack - cron-maintenance-app in us-west-2
   ```

1. 此外，您可以透過開啟 Lambda 主控台的[函數](https://console.aws.amazon.com/lambda/home#/functions)頁面，進一步確認該 Lambda 函數已成功建立。您應該會看到名為 `ScheduledDBMaintenance` 的函數。

------

## 測試應用程式
<a name="scheduled-task-app-test-app"></a>

 若要測試排程是否能夠正確觸發函數，以及函數是否能夠正確清除資料庫中的記錄，您可以暫時修改排程，以在特定時間執行一次。然後，您可以再次執行 `sam deploy`，將週期性排程重設為每月執行一次。

**使用 執行應用程式 AWS 管理主控台**

1. 導覽回 EventBridge 排程器主控台頁面。

1. 選擇相應排程，然後選擇**編輯**。

1. 在**排程模式**區段的**週期**下，選擇**一次性排程**。

1.  將調用時間設定為幾分鐘後並檢閱設定，然後選擇**儲存**。

 在排程執行並調用其目標之後，您可以執行 `test_app.py` 指令碼，以確認函數已成功從 DynamoDB 資料表移除所有舊記錄。

**若要使用 Python 指令碼驗證舊記錄是否已被刪除**

1.  在命令列中，導覽至儲存 `test_app.py` 的資料夾。

1. 執行指令碼。

   ```
   python test_app.py
   ```

    如果成功，您就會看到以下輸出。

   ```
   Total number of old records: 0
   ```

## 後續步驟
<a name="scheduled-task-app-next-steps"></a>

 您現在可以根據自己特定的應用程式需求，修改 EventBridge 排程器排程。EventBridge Sch排程器支援以下排程表達式：cron、rate 和 one-time schedules。

 如需有關 EventBridge 排程器排程表達式的詳細資訊，請參閱 *EventBridge Scheduler User Guide* 中的 [Schedule types](https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html)。*IAM User Guide* 中的 [Access Management](https://docs.aws.amazon.com/IAM/latest/UserGuide/access.html) 