

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

# 請求在 DynamoDB 中匯出資料表
<a name="S3DataExport_Requesting"></a>

DynamoDB 資料表匯出可讓您將資料表資料匯出至 Amazon S3 儲存貯體，讓您使用 Athena、 AWS Glue、Amazon SageMaker AI、Amazon EMR 和 等 AWS 其他服務，對資料執行分析和複雜的查詢 AWS Lake Formation。您可以使用 AWS 管理主控台、 AWS CLI或 DynamoDB API 請求資料表匯出。

**注意**  
不支援申請者支付 Amazon S3 儲存貯體。

DynamoDB 同時支援完整匯出和增量匯出：
+ 使用**完整匯出**時，您可以從時間點復原 (PITR) 時段內任何時間點，將資料表的完整快照匯出至 Amazon S3 儲存貯體。
+ 使用**增量匯出**時，您可以將 PITR 時段中指定期間內變更、更新或刪除的 DynamoDB 資料表中的資料匯出至 Amazon S3 儲存貯體。

**Topics**
+ [先決條件](#S3DataExport_Requesting_Permissions)
+ [使用 請求匯出 AWS 管理主控台](#S3DataExport_Requesting_Console)
+ [取得 中過去匯出的詳細資訊 AWS 管理主控台](#S3DataExport_Requesting_Console_Details)
+ [使用 AWS CLI 和 AWS SDKs 請求匯出](#S3DataExport_Requesting_CLI)
+ [使用 AWS CLI 和 AWS SDKs 取得過去匯出的詳細資訊](#S3DataExport_Requesting_CLI_Details)

## 先決條件
<a name="S3DataExport_Requesting_Permissions"></a>

**啟用 PITR**

若要使用匯出至 S3 功能，您將需要在資料表上啟用 PITR。如需如何啟用 PITR 的詳細資訊，請參閱[時間點復原](PointInTimeRecovery_Howitworks.md)。如果您請求匯出未啟用 PITR 的資料表，您的請求將會失敗，並顯示例外狀況訊息：「呼叫 `ExportTableToPointInTime` 操作時發生錯誤 (PointInTimeRecoveryUnavailableException)：資料表 'my-dynamodb-table' 未啟用時間點復原」。您只能從設定 PITR `RecoveryPeriodInDays` 內的時間點請求和匯出。

**設定 S3 許可**

您可以將資料表資料匯出至您擁有寫入許可的任何 Amazon S3 儲存貯體。目的地儲存貯體不需要與來源資料表擁有者位於相同 AWS 區域或擁有相同的擁有者。您的 AWS Identity and Access Management (IAM) 政策需要允許您執行 S3 動作 (`s3:AbortMultipartUpload`、 `s3:PutObject`和 `s3:PutObjectAcl`) 和 DynamoDB 匯出動作 (`dynamodb:ExportTableToPointInTime`)。以下範例政策將授予您的使用者執行匯出至 S3 儲存貯體的許可。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowDynamoDBExportAction",
            "Effect": "Allow",
            "Action": "dynamodb:ExportTableToPointInTime",
            "Resource": "arn:aws:dynamodb:us-east-1:111122223333:table/my-table"
        },
        {
            "Sid": "AllowS3BucketWrites",
            "Effect": "Allow",
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
        }
    ]
}
```

------

如果您需要寫入另一個帳戶中的 S3 儲存貯體，或者您沒有寫入其中的許可，則 S3 儲存貯體擁有者將需要新增儲存貯體政策，以允許您從 DynamoDB 匯出至該儲存貯體。以下是目標 S3 儲存貯體的範例政策。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "ExampleStatement",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:user/Dave"
            },
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
        }
    ]
}
```

------

在匯出過程中撤銷這些許可會產生部分檔案。

**注意**  
如果您要匯出的目標資料表或儲存貯體使用客戶自管金鑰加密，該 KMS 金鑰的政策必須允許 DynamoDB 使用該金鑰。此許可是透過觸發匯出任務的 IAM 使用者/角色授予。如需有關加密及其最佳實務的詳細資訊，請參閱 [DynamoDB 如何使用 AWS KMS](https://docs.aws.amazon.com/kms/latest/developerguide/services-dynamodb.html) 以及[使用自訂 KMS 金鑰](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/encryption.howitworks.html#managed-key-customer-managed)。

## 使用 請求匯出 AWS 管理主控台
<a name="S3DataExport_Requesting_Console"></a>

以下範例示範如何使用 DynamoDB 主控台匯出名為 `MusicCollection` 的現有資料表。

**注意**  
此程序假設您已經啟用時間點復原。若要為 `MusicCollection` 資料表啟用該功能，進入資料表 **Overview** (概觀) 索引標籤的 **Table details** (資料表詳細資訊) 部分，然後為 **Point-in-time recovery** (時間點復原) 選擇 **Enable** (啟用)。

**請求資料表匯出**

1. 登入 AWS 管理主控台 ，並在 https：//[https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/) 開啟 DynamoDB 主控台。

1. 在主控台左側的導覽窗格中，選擇 **Exports to S3** (匯出至 S3)。

1. 選取**匯出至 S3** 按鈕。

1. 選擇來源資料表和目的地 S3 儲存貯體。如果您的帳戶擁有該目的地儲存貯體，您可以使用 **Browse S3** (瀏覽 S3) 按鈕尋找它。如果不是，請使用 `s3://bucketname/prefix format.` 輸入儲存貯體的 URL；**prefix** 是有助於您整理目的地儲存貯體的選用資料夾。

1. 選擇**完整匯出**或**增量匯出**。**完整匯出**會輸出資料表在您所指定時間點的完整資料表快照。**增量匯出**會輸出在指定匯出期間對資料表所做的變更。您的輸出會經過壓縮，因此只會包含匯出期間內項目的最終狀態。即使項目在同一匯出期間內有多個更新，該項目也只會在匯出中出現一次。

------
#### [ Full export ]

   1. 選取您要匯出完整資料表快照的來源時間點。這個時間點可以是 PITR 時段內的任何時間點。或者，您可以選取**目前時間**以匯出最新快照。

   1. 對於**匯出的檔案格式**，請選擇 **DynamoDB JSON** 和 **Amazon Ion** 兩者之一。根據預設，您的資料表會以 DynamoDB JSON 格式在時間點復原時段中的最近可還原時間匯出，並使用 Amazon S3 金鑰 (SSE-S3) 進行加密。您可以視需要變更這些匯出設定。
**注意**  
如果您選擇使用受 AWS Key Management Service (AWS KMS) 保護的金鑰來加密匯出，則金鑰必須位於與目的地 S3 儲存貯體相同的區域。

------
#### [ Incremental export ]

   1. 選取您要匯出增量資料的**匯出期間**。選擇在 PITR 時段內的開始時間。匯出期間必須至少為 15 分鐘，且不超過 24 小時。匯出期間的開始時間包含在內，結束時間則不包含在內。

   1. 選擇**絕對模式**或**相對模式**。

      1. **絕對模式**會依您指定的期間匯出增量資料。

      1. **相對模式**會在相對於匯出任務提交時間的匯出期間匯出增量資料。

   1. 對於**匯出的檔案格式**，請選擇 **DynamoDB JSON** 和 **Amazon Ion** 兩者之一。根據預設，您的資料表會以 DynamoDB JSON 格式在時間點復原時段中的最近可還原時間匯出，並使用 Amazon S3 金鑰 (SSE-S3) 進行加密。您可以視需要變更這些匯出設定。
**注意**  
如果您選擇使用受 AWS Key Management Service (AWS KMS) 保護的金鑰來加密匯出，則金鑰必須位於與目的地 S3 儲存貯體相同的區域。

   1. 對於**匯出檢視類型**，請選取**新舊映像**或**僅限新映像**。新映像提供項目的最新狀態。舊映像提供項目在指定的「開始日期和時間」之前的狀態。預設設定為**新舊映像**。如需新映像和舊映像的詳細資訊，請參閱 [增量匯出輸出](S3DataExport.Output.md#incremental-export-output)。

------

1. 選擇**匯出**以開始。

匯出的資料在交易上不一致。您的交易操作可能在兩次匯出輸出之間未完成。您可能看到經交易操作修改的項目子集反映在匯出中，而同一交易中的另一個修改內容子集卻未反映在相同的匯出請求中。不過，匯出最後會是一致的。如果交易在匯出期間未完成，交易的其餘部分保證會在下一次連續匯出中出現，而且不會重複。用於匯出的期間是以內部系統時鐘為基礎，且可能與您的應用程式本機時鐘相差一分鐘。

## 取得 中過去匯出的詳細資訊 AWS 管理主控台
<a name="S3DataExport_Requesting_Console_Details"></a>

按一下導覽側邊欄中的**匯出至 S3** 區段，即可找到您過去曾執行的匯出任務的相關資訊。此區段包含您在過去 90 天內建立的所有匯出清單。選取**匯出**索引標籤中所列出任務的 ARN 以擷取該匯出的相關資訊，包括您選擇的任何進階組態設定。請注意，雖然匯出任務中繼資料會在 90 天後過期，也無法在此清單中找到早於該時間的任務，但只要儲存貯體政策允許，S3 儲存貯體中的物件就會保留。DynamoDB 絕不會刪除在匯出時其在您的 S3 儲存貯體中建立的任何物件。

## 使用 AWS CLI 和 AWS SDKs 請求匯出
<a name="S3DataExport_Requesting_CLI"></a>

下列範例示範如何將現有資料表匯出至 S3 儲存貯體。

**注意**  
此程序假設您已經啟用時間點復原。若要針對 `MusicCollection` 資料表啟用程序，請執行下列命令。  

```
aws dynamodb update-continuous-backups \
    --table-name MusicCollection \
    --point-in-time-recovery-specification PointInTimeRecoveryEnabled=True
```

**完整匯出**

------
#### [ AWS CLI ]

**注意**  
如果要求跨帳戶資料表匯出，請務必包含 `--s3-bucket-owner` 選項。

```
aws dynamodb export-table-to-point-in-time \
  --table-arn arn:aws:dynamodb:us-west-2:111122223333:table/MusicCollection \
  --s3-bucket ddb-export-musiccollection-9012345678 \
  --s3-prefix 2020-Nov \
  --export-format DYNAMODB_JSON \
  --export-time 1604632434 \
  --s3-bucket-owner 9012345678 \
  --s3-sse-algorithm AES256
```

------
#### [ Python ]

```
import boto3
from datetime import datetime

client = boto3.client('dynamodb')

client.export_table_to_point_in_time(
    TableArn='arn:aws:dynamodb:us-east-1:111122223333:table/TABLE',
    ExportTime=datetime(2023, 9, 20, 12, 0, 0),
    S3Bucket='bucket',
    S3Prefix='prefix',
    S3SseAlgorithm='AES256',
    ExportFormat='DYNAMODB_JSON'
)
```

------
#### [ Java ]

```
DynamoDbClient client = DynamoDbClient.create();

client.exportTableToPointInTime(b -> b
    .tableArn("arn:aws:dynamodb:us-east-1:111122223333:table/TABLE")
    .exportTime(Instant.parse("2023-09-20T12:00:00Z"))
    .s3Bucket("bucket")
    .s3Prefix("prefix")
    .s3SseAlgorithm(S3SseAlgorithm.AES256)
    .exportFormat(ExportFormat.DYNAMODB_JSON));
```

------
#### [ .NET ]

```
var client = new AmazonDynamoDBClient();

await client.ExportTableToPointInTimeAsync(new ExportTableToPointInTimeRequest
{
    TableArn = "arn:aws:dynamodb:us-east-1:111122223333:table/TABLE",
    ExportTime = new DateTime(2023, 9, 20, 12, 0, 0, DateTimeKind.Utc),
    S3Bucket = "bucket",
    S3Prefix = "prefix",
    S3SseAlgorithm = S3SseAlgorithm.AES256,
    ExportFormat = ExportFormat.DYNAMODB_JSON
});
```

------
#### [ JavaScript ]

```
import { DynamoDBClient, ExportTableToPointInTimeCommand } from "@aws-sdk/client-dynamodb";

const client = new DynamoDBClient();

await client.send(new ExportTableToPointInTimeCommand({
    TableArn: "arn:aws:dynamodb:us-east-1:111122223333:table/TABLE",
    ExportTime: new Date("2023-09-20T12:00:00Z"),
    S3Bucket: "bucket",
    S3Prefix: "prefix",
    S3SseAlgorithm: "AES256",
    ExportFormat: "DYNAMODB_JSON"
}));
```

------
#### [ Go ]

```
cfg, _ := config.LoadDefaultConfig(context.TODO())
client := dynamodb.NewFromConfig(cfg)

exportTime := time.Date(2023, 9, 20, 12, 0, 0, 0, time.UTC)
client.ExportTableToPointInTime(context.TODO(), &dynamodb.ExportTableToPointInTimeInput{
    TableArn:       aws.String("arn:aws:dynamodb:us-east-1:111122223333:table/TABLE"),
    ExportTime:     &exportTime,
    S3Bucket:       aws.String("bucket"),
    S3Prefix:       aws.String("prefix"),
    S3SseAlgorithm: types.S3SseAlgorithmAes256,
    ExportFormat:   types.ExportFormatDynamodbJson,
})
```

------

**增量匯出**

------
#### [ AWS CLI ]

```
aws dynamodb export-table-to-point-in-time \
  --table-arn arn:aws:dynamodb:REGION:ACCOUNT:table/TABLENAME \
  --s3-bucket BUCKET --s3-prefix PREFIX \
  --incremental-export-specification ExportFromTime=1693569600,ExportToTime=1693656000,ExportViewType=NEW_AND_OLD_IMAGES \
  --export-type INCREMENTAL_EXPORT
```

------
#### [ Python ]

```
import boto3
from datetime import datetime

client = boto3.client('dynamodb')

client.export_table_to_point_in_time(
    TableArn='arn:aws:dynamodb:us-east-1:111122223333:table/TABLE',
    IncrementalExportSpecification={
      'ExportFromTime': datetime(2023, 9, 20, 12, 0, 0),
      'ExportToTime': datetime(2023, 9, 20, 13, 0, 0),
      'ExportViewType': 'NEW_AND_OLD_IMAGES'
    },
    ExportType='INCREMENTAL_EXPORT',
    S3Bucket='bucket',
    S3Prefix='prefix',
    S3SseAlgorithm='AES256',
    ExportFormat='DYNAMODB_JSON'
)
```

------
#### [ Java ]

```
DynamoDbClient client = DynamoDbClient.create();

client.exportTableToPointInTime(b -> b
    .tableArn("arn:aws:dynamodb:us-east-1:111122223333:table/TABLE")
    .exportType(ExportType.INCREMENTAL_EXPORT)
    .incrementalExportSpecification(i -> i
        .exportFromTime(Instant.parse("2023-09-20T12:00:00Z"))
        .exportToTime(Instant.parse("2023-09-20T13:00:00Z"))
        .exportViewType(ExportViewType.NEW_AND_OLD_IMAGES))
    .s3Bucket("bucket")
    .s3Prefix("prefix")
    .s3SseAlgorithm(S3SseAlgorithm.AES256)
    .exportFormat(ExportFormat.DYNAMODB_JSON));
```

------
#### [ .NET ]

```
var client = new AmazonDynamoDBClient();

await client.ExportTableToPointInTimeAsync(new ExportTableToPointInTimeRequest
{
    TableArn = "arn:aws:dynamodb:us-east-1:111122223333:table/TABLE",
    ExportType = ExportType.INCREMENTAL_EXPORT,
    IncrementalExportSpecification = new IncrementalExportSpecification
    {
        ExportFromTime = new DateTime(2023, 9, 20, 12, 0, 0, DateTimeKind.Utc),
        ExportToTime = new DateTime(2023, 9, 20, 13, 0, 0, DateTimeKind.Utc),
        ExportViewType = ExportViewType.NEW_AND_OLD_IMAGES
    },
    S3Bucket = "bucket",
    S3Prefix = "prefix",
    S3SseAlgorithm = S3SseAlgorithm.AES256,
    ExportFormat = ExportFormat.DYNAMODB_JSON
});
```

------
#### [ JavaScript ]

```
import { DynamoDBClient, ExportTableToPointInTimeCommand } from "@aws-sdk/client-dynamodb";

const client = new DynamoDBClient();

await client.send(new ExportTableToPointInTimeCommand({
    TableArn: "arn:aws:dynamodb:us-east-1:111122223333:table/TABLE",
    ExportType: "INCREMENTAL_EXPORT",
    IncrementalExportSpecification: {
        ExportFromTime: new Date("2023-09-20T12:00:00Z"),
        ExportToTime: new Date("2023-09-20T13:00:00Z"),
        ExportViewType: "NEW_AND_OLD_IMAGES"
    },
    S3Bucket: "bucket",
    S3Prefix: "prefix",
    S3SseAlgorithm: "AES256",
    ExportFormat: "DYNAMODB_JSON"
}));
```

------
#### [ Go ]

```
cfg, _ := config.LoadDefaultConfig(context.TODO())
client := dynamodb.NewFromConfig(cfg)

fromTime := time.Date(2023, 9, 20, 12, 0, 0, 0, time.UTC)
toTime := time.Date(2023, 9, 20, 13, 0, 0, 0, time.UTC)
client.ExportTableToPointInTime(context.TODO(), &dynamodb.ExportTableToPointInTimeInput{
    TableArn:   aws.String("arn:aws:dynamodb:us-east-1:111122223333:table/TABLE"),
    ExportType: types.ExportTypeIncrementalExport,
    IncrementalExportSpecification: &types.IncrementalExportSpecification{
        ExportFromTime: &fromTime,
        ExportToTime:   &toTime,
        ExportViewType: types.ExportViewTypeNewAndOldImages,
    },
    S3Bucket:       aws.String("bucket"),
    S3Prefix:       aws.String("prefix"),
    S3SseAlgorithm: types.S3SseAlgorithmAes256,
    ExportFormat:   types.ExportFormatDynamodbJson,
})
```

------

**注意**  
如果您選擇使用受 AWS Key Management Service (AWS KMS) 保護的金鑰來加密匯出，則金鑰必須位於與目的地 S3 儲存貯體相同的區域。

## 使用 AWS CLI 和 AWS SDKs 取得過去匯出的詳細資訊
<a name="S3DataExport_Requesting_CLI_Details"></a>

使用 `list-exports` 命令即可找到您過去曾執行之匯出請求的相關資訊。此命令會傳回您在過去 90 天內建立的所有匯出清單。請注意，雖然匯出任務中繼資料會在 90 天後過期，也無法使用 `list-exports` 命令傳回早於該時間的任務，但只要儲存貯體政策允許，S3 儲存貯體中的物件就會保留。DynamoDB 絕不會刪除在匯出時其在您的 S3 儲存貯體中建立的任何物件。

在匯出成功或失敗之前，其狀態會是 `PENDING`。如果成功，狀態將變更為 `COMPLETED`。如果失敗，狀態將變更為 `FAILED` 並帶有 `failure_message` 和 `failure_reason`。

**列出匯出**

------
#### [ AWS CLI ]

```
aws dynamodb list-exports \
    --table-arn arn:aws:dynamodb:us-east-1:111122223333:table/ProductCatalog
```

------
#### [ Python ]

```
import boto3

client = boto3.client('dynamodb')

print(
  client.list_exports(
     TableArn='arn:aws:dynamodb:us-east-1:111122223333:table/TABLE',
  )
)
```

------
#### [ Java ]

```
DynamoDbClient client = DynamoDbClient.create();

ListExportsResponse response = client.listExports(b -> b
    .tableArn("arn:aws:dynamodb:us-east-1:111122223333:table/TABLE"));

response.exportSummaries().forEach(System.out::println);
```

------
#### [ .NET ]

```
var client = new AmazonDynamoDBClient();

var response = await client.ListExportsAsync(new ListExportsRequest
{
    TableArn = "arn:aws:dynamodb:us-east-1:111122223333:table/TABLE"
});

response.ExportSummaries.ForEach(Console.WriteLine);
```

------
#### [ JavaScript ]

```
import { DynamoDBClient, ListExportsCommand } from "@aws-sdk/client-dynamodb";

const client = new DynamoDBClient();

const response = await client.send(new ListExportsCommand({
    TableArn: "arn:aws:dynamodb:us-east-1:111122223333:table/TABLE"
}));

console.log(response.ExportSummaries);
```

------
#### [ Go ]

```
cfg, _ := config.LoadDefaultConfig(context.TODO())
client := dynamodb.NewFromConfig(cfg)

response, _ := client.ListExports(context.TODO(), &dynamodb.ListExportsInput{
    TableArn: aws.String("arn:aws:dynamodb:us-east-1:111122223333:table/TABLE"),
})

fmt.Println(response.ExportSummaries)
```

------

**描述匯出**

------
#### [ AWS CLI ]

```
aws dynamodb describe-export \
    --export-arn arn:aws:dynamodb:us-east-1:111122223333:table/ProductCatalog/export/01695353076000-a1b2c3d4
```

------
#### [ Python ]

```
import boto3

client = boto3.client('dynamodb')

print(
  client.describe_export(
     ExportArn='arn:aws:dynamodb:us-east-1:111122223333:table/TABLE/export/01695353076000-06e2188f',
  )['ExportDescription']
)
```

------
#### [ Java ]

```
DynamoDbClient client = DynamoDbClient.create();

DescribeExportResponse response = client.describeExport(b -> b
    .exportArn("arn:aws:dynamodb:us-east-1:111122223333:table/TABLE/export/01695353076000-06e2188f"));

System.out.println(response.exportDescription());
```

------
#### [ .NET ]

```
var client = new AmazonDynamoDBClient();

var response = await client.DescribeExportAsync(new DescribeExportRequest
{
    ExportArn = "arn:aws:dynamodb:us-east-1:111122223333:table/TABLE/export/01695353076000-06e2188f"
});

Console.WriteLine(response.ExportDescription);
```

------
#### [ JavaScript ]

```
import { DynamoDBClient, DescribeExportCommand } from "@aws-sdk/client-dynamodb";

const client = new DynamoDBClient();

const response = await client.send(new DescribeExportCommand({
    ExportArn: "arn:aws:dynamodb:us-east-1:111122223333:table/TABLE/export/01695353076000-06e2188f"
}));

console.log(response.ExportDescription);
```

------
#### [ Go ]

```
cfg, _ := config.LoadDefaultConfig(context.TODO())
client := dynamodb.NewFromConfig(cfg)

response, _ := client.DescribeExport(context.TODO(), &dynamodb.DescribeExportInput{
    ExportArn: aws.String("arn:aws:dynamodb:us-east-1:111122223333:table/TABLE/export/01695353076000-06e2188f"),
})

fmt.Println(response.ExportDescription)
```

------