View a markdown version of this page

在 DynamoDB 中请求表导出 - Amazon DynamoDB

在 DynamoDB 中请求表导出

DynamoDB 表导出支持您将表数据导出到 Amazon S3 存储桶,同时使您可以通过其它 AWS 服务(如 Athena、AWS Glue、Amazon SageMaker AI、Amazon EMR 和 AWS Lake Formation)对数据执行分析和复杂的查询。可以使用 AWS 管理控制台、AWS CLI 或 DynamoDB API 请求表导出。

注意

不支持申请方付款 Amazon S3 存储桶。

DynamoDB 同时支持完整导出和增量导出:

  • 使用完整导出,可以在从时间点故障恢复(PITR)时段内的任何时间点,将表的完整快照导出到 Amazon S3 桶。

  • 通过增量导出,您可以将 DynamoDB 表中在 PITR 时段的指定时间段内已更改、更新或删除的数据导出到 AmazonS3 桶中。

先决条件

启用 PITR

要使用导出到 S3 特征,您必须对表启用 PITR。有关如何启用 PITR 的详细信息,请参阅时间点故障恢复。如果您请求导出未启用 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/*" } ] }

如果您需要写入其他账户中的 Amazon S3 存储桶,或者您没有写入权限,则 Amazon S3 存储桶拥有者必须添加存储桶策略来允许您从 DynamoDB 导出到该存储桶。以下是有关目标 Amazon 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/*" } ] }

导出时撤消这些权限将导致部分文件。

注意

您必须使用与源表相同的 AWS 账户中的主体身份调用 ExportTableToPointInTime。尽管目标存储桶可以属于不同的账户(如前所述),但导出请求本身由表的账户发起。其他账户发起的请求会失败并显示 ValidationException:“只有与资源所有者账户匹配的账户才支持此操作。” 要导出其他账户拥有的表,请在表的账户中代入 IAM 角色,然后使用该角色的凭证发起导出请求。当该角色写入其他账户中的存储桶时,请包括存储桶所有者,并在存储桶策略中向该角色授予写入权限,如上所述。

注意

如果您要导出到的目标表或桶使用了客户管理的密钥加密,则该 KMS 密钥的策略必须赋予 DynamoDB 使用该密钥的权限。此权限是通过触发导出任务的 IAM 用户/角色授予的。有关加密的更多信息,包括最佳实践,请参阅 DynamoDB 如何使用 AWS KMS 和使用自定义 KMS 密钥。

请求使用 AWS 管理控制台 导出

下面的示例演示如何使用 DynamoDB 控制台导出名为 MusicCollection 的现有表。

注意

此过程假定已启用时间点恢复。要在 MusicCollection 表中启用,在表的概述选项卡的表详细信息部分,为时间点恢复选择启用。

请求表导出
  1. 登录 AWS 管理控制台,打开 DynamoDB 控制台:https://console.aws.amazon.com/dynamodb/。

  2. 在控制台左侧的导航窗格中,选择流和导出。

  3. 选择导出到 S3 按钮。

  4. 选择源表和目标 S3 存储桶。如果目标存储桶为您的账户所拥有,则您可以使用 Browse S3(浏览 S3)按钮查找它。否则,使用 s3://bucketname/prefix format. 输入存储桶的 URL,prefix 是一个可选文件夹,有助于您的目标存储桶保持井然有序。

  5. 选择完整导出或增量导出。完整导出会按照您指定的时间点输出表的完整表快照。增量导出会输出在指定的导出期间对表所做的更改。您的输出经过压缩,以便只包含导出期间项目的最终状态。即使该项目在同一导出期间内有多个更新,也只会在导出中出现一次。

    Full export
    1. 选择要从中导出完整表快照的时间点。这可以是 PITR 时段内的任何时间点。或者,您可以选择当前时间以导出最新的快照。

    2. 对于导出的文件格式,请在 DynamoDB JSON 和 Amazon Ion 之间进行选择。默认表将从时间点恢复窗口中的最新可还原时间以 DynamoDB JSON 格式导出,并使用 Amazon S3 密钥 (SSE-S3) 加密。您可以根据需要更改这些导出设置。

      注意

      如果选择使用 AWS Key Management Service (AWS KMS) 保护的密钥对导出进行加密,则密钥必须与目标 S3 存储桶位于同一区域。

    Incremental export
    1. 选择要针对其导出增量数据的导出期间。在 PITR 时段中选择开始时间。导出期间持续时间必须至少为 15 分钟,且不超过 24 小时。导出期间的开始时间包含在内,结束时间不包括在内。

    2. 在绝对模式或相对模式之间进行选择。

      1. 绝对模式将导出您指定的时间段内的增量数据。

      2. 相对模式将在相对于导出任务提交时间的导出期间内导出增量数据。

    3. 对于导出的文件格式,请在 DynamoDB JSON 和 Amazon Ion 之间进行选择。默认表将从时间点恢复窗口中的最新可还原时间以 DynamoDB JSON 格式导出,并使用 Amazon S3 密钥 (SSE-S3) 加密。您可以根据需要更改这些导出设置。

      注意

      如果选择使用 AWS Key Management Service (AWS KMS) 保护的密钥对导出进行加密,则密钥必须与目标 S3 存储桶位于同一区域。

    4. 对于导出视图类型,选择新旧映像或仅限新映像。新映像提供项目的最新状态。旧映像提供项目在指定的“开始日期和时间”之前的状态。原定设置为新旧映像。有关新映像和旧映像的更多信息,请参阅增量导出输出。

  6. 选择导出以开始。

导出的数据在事务上不一致。您的事务操作可能会在两个导出输出之间发生损坏。可能通过导出中反映的事务操作修改了项目的子集,而同一事务中的另一个修改子集未反映在同一个导出请求中。但是,导出最终是一致的。如果事务在导出过程中损坏,则您将在下一次相邻导出中具有剩余的事务,而没有重复。用于导出的时间段基于内部系统时钟,可能与应用程序的本地时钟相差一分钟。

获取 AWS 管理控制台 中以前导出的详细信息

通过选择导航侧边栏中的导出到 S3 部分,可以找到有关您过去运行的导出任务的信息。此部分包含过去 90 天内创建的所有导出的列表。选择导出选项卡中所列任务的 ARN 来检索有关该导出的信息,包括您选择的任何高级配置设置。请注意,尽管导出任务元数据会在 90 天后过期,列表中没有早于该日期的作业,但 S3 存储桶中的数据元将保持存储桶策略允许的时间。导出时,DynamoDB 不删除 S3 存储桶中创建的任何对象。

使用 AWS CLI 和 AWS SDK 请求导出

下面的示例演示如何将现有表导出到 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 SDK 获取有关以前导出的详细信息

可以使用 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)