【发布时间】:2013-09-24 15:14:46
【问题描述】:
是否可以以某种格式从 DynamoDB 表中导出数据?
具体的用例是我想从我的生产 dynamodb 数据库中导出数据并将该数据导入我的本地 dynamodb 实例,这样我的应用程序就可以使用本地数据副本而不是生产数据。
我使用link 作为 DynamoDB 的本地实例。
【问题讨论】:
标签: amazon-web-services amazon-dynamodb amazon-dynamodb-local
是否可以以某种格式从 DynamoDB 表中导出数据?
具体的用例是我想从我的生产 dynamodb 数据库中导出数据并将该数据导入我的本地 dynamodb 实例,这样我的应用程序就可以使用本地数据副本而不是生产数据。
我使用link 作为 DynamoDB 的本地实例。
【问题讨论】:
标签: amazon-web-services amazon-dynamodb amazon-dynamodb-local
有一个工具叫DynamoDBtoCSV
可用于将所有数据导出到 CSV 文件。但是,相反,您将不得不构建自己的工具。我的建议是您将此功能添加到该工具中,并将其贡献给 Git 存储库。
另一种方法是使用 AWS Data Pipeline 执行此任务(您将节省从 AWS 基础设施外部读取数据的所有成本)。方法类似:
【讨论】:
sudo npm install -g dynamodbexportcsv; DynamoDbExportCsv --table "yourtable" --awsregion "us-east-1" --columns "col1,col2,col3" --scans 8 --gzip; cat *.gz > combined.csv.gz
试试我的简单 node.js 脚本dynamo-archive。它以 JSON 格式导出和导入。
【讨论】:
Dynamo DB 现在提供了一种向 S3 导出和导入数据的方法 http://aws.amazon.com/about-aws/whats-new/2014/03/06/announcing-dynamodb-cross-region-export-import/
【讨论】:
将其从 DynamoDB 界面导出到 S3。
然后使用 sed 将其转换为 Json:
sed -e 's/$/}/' -e $'s/\x02/,"/g' -e $'s/\x03/":/g' -e 's/^/{"/' <exported_table> > <exported_table>.json
【讨论】:
我发现当前用于简单导入/导出(包括通过 DynamoDB Local 往返)的最佳工具是这个 Python 脚本:
https://github.com/bchew/dynamodump
此脚本支持架构导出/导入以及数据导入/导出。它还使用批处理 API 进行高效操作。
我已成功使用它从 DynamoDB 表中获取数据到本地 DynamoDB 以用于开发目的,它非常适合我的需求。
【讨论】:
对于那些宁愿使用 java 执行此操作的人,DynamodbToCSV4j。
JSONObject config = new JSONObject();
config.put("accessKeyId","REPLACE");
config.put("secretAccessKey","REPLACE");
config.put("region","eu-west-1");
config.put("tableName","testtable");
d2csv d = new d2csv(config);
【讨论】:
在 DynamoDB Web 控制台中选择您的表,而不是 Actions -> Export/Import
【讨论】:
我创建了一个实用程序类来帮助开发人员进行导出。如果您不想使用 AWS 的数据管道功能,可以使用此功能。 git hub repo 的链接是 -here
【讨论】:
如果您需要,您可以使用此方法将 Dynamo 数据转换为 JSON https://2json.net/dynamo
【讨论】:
在一个类似的用例中,我使用 DynamoDB Streams 来触发 AWS Lambda,它基本上写入了我的 DW 实例。您可能可以编写 Lambda 以将每个表更改写入您的非生产账户中的表。这样一来,您的 Devo 表也将保持与 Prod 非常接近。
【讨论】:
这会将所有项目导出为 jsons 文档
aws dynamodb scan --table-name TABLE_NAME > export.json
此脚本将从远程 dynamodb 表中读取并将完整表导入本地。
TABLE=YOURTABLE
maxItems=25
index=0
DATA=$(aws dynamodb scan --table-name $TABLE --max-items $maxItems)
((index+=1))
echo $DATA | jq ".Items | {\"$TABLE\": [{\"PutRequest\": { \"Item\": .[]}}]}" > inserts.jsons
aws dynamodb batch-write-item --request-items file://inserts.jsons --endpoint-url http://localhost:8000
nextToken=$(echo $DATA | jq '.NextToken')
while [[ "${nextToken}" != "" ]]
do
DATA=$(aws dynamodb scan --table-name $TABLE --max-items $maxItems --starting-token $nextToken)
((index+=1))
echo $DATA | jq ".Items | {\"$TABLE\": [{\"PutRequest\": { \"Item\": .[]}}]}" > inserts.jsons
aws dynamodb batch-write-item --request-items file://inserts.jsons --endpoint-url http://localhost:8000
nextToken=$(echo $DATA | jq '.NextToken')
done
这是一个脚本版本,它使用文件将导出的数据保存在磁盘上。
TABLE=YOURTABLE
maxItems=25
index=0
DATA=$(aws dynamodb scan --table-name $TABLE --max-items $maxItems)
((index+=1))
echo $DATA | cat > "$TABLE-$index.json"
nextToken=$(echo $DATA | jq '.NextToken')
while [[ "${nextToken}" != "" ]]
do
DATA=$(aws dynamodb scan --table-name $TABLE --max-items $maxItems --starting-token $nextToken)
((index+=1))
echo $DATA | cat > "$TABLE-$index.json"
nextToken=$(echo $DATA | jq '.NextToken')
done
for x in `ls *$TABLE*.json`; do
cat $x | jq ".Items | {\"$TABLE\": [{\"PutRequest\": { \"Item\": .[]}}]}" > inserts.jsons
aws dynamodb batch-write-item --request-items file://inserts.jsons --endpoint-url http://localhost:8000
done
【讨论】:
\n),此脚本用 JSON 文件中的实际换行符替换转义的换行符 - 从而将 jq 调用中断为:parse error: Invalid string: control characters from U+0000 through U+001F must be escaped at line 2, column 23。我用sed 解决了双重转义\n
这是一种使用aws cli 和jq 从表中导出一些 数据(通常我们只想在本地获取产品数据的样本)的方法。
假设我们有一个名为 my-prod-table 的 prod 表和一个名为 my-local-table 的本地表
要导出数据,请运行以下命令:
aws dynamodb scan --table-name my-prod-table \
| jq '{"my-local-table": [.Items[] | {PutRequest: {Item: .}}]}' > data.json
基本上,我们扫描 prod 表,将扫描输出转换为 batchWriteItem 的格式,然后将结果转储到文件中。
要在本地表中导入数据,请运行:
aws dynamodb batch-write-item \
--request-items file://data.json \
--endpoint-url http://localhost:8000
注意:batch-write-item 请求存在一些限制 - BatchWriteItem 操作最多可以包含 25 个单独的 PutItem 和 DeleteItem 请求,并且最多可以写入 16 MB 的数据。 (单个项目的最大大小为 400 KB。)。
【讨论】:
我使用了很棒的网络厨师网站...https://gchq.github.io/CyberChef
使用csv to json 工具。
【讨论】:
我认为我的回答与 Ivailo Bardarov 更相似,如果计划从 linux 实例运行这个,请运行这个
1.登录到您的 AWS 账户并转到 IAM 为角色创建具有有限策略的用户(当然是出于安全目的)。这应该仅限于读取您要备份的 dynamodb 表。
2.复制访问密钥和秘密并更新以下命令以在 Linux 上运行它(但请确保您的表不是很大,并且可能会为您运行它的机器创建空间问题)
AWS_ACCESS_KEY_ID='put_your_key' AWS_SECRET_ACCESS_KEY='put_your_secret' aws --region='put_your_region' dynamodb scan --table-name 'your_table_name'>> export_$(date "+%F-%T").json
注意类似的命令可以在 Windows/Powershell 上执行,我没有测试,所以这里就不加了。
【讨论】:
扩展@Ivailo Bardarov 的答案,我编写了以下脚本,将远程 DynamoDB 中的表复制到本地:
#!/bin/bash
declare -a arr=("table1" "table2" "table3" "table4")
for i in "${arr[@]}"
do
TABLE=$i
maxItems=25
index=0
echo "Getting table description of $TABLE from remote database..."
aws dynamodb describe-table --table-name $TABLE > table-description.json
echo
echo "Creating table $TABLE in the local database..."
ATTRIBUTE_DEFINITIONS=$(jq .Table.AttributeDefinitions table-description.json)
KEY_SCHEMA=$(jq .Table.KeySchema table-description.json)
BILLING_MODE=$(jq .Table.BillingModeSummary.BillingMode table-description.json)
READ_CAPACITY_UNITS=$(jq .Table.ProvisionedThroughput.ReadCapacityUnits table-description.json)
WRITE_CAPACITY_UNITS=$(jq .Table.ProvisionedThroughput.WriteCapacityUnits table-description.json)
TABLE_DEFINITION=""
if [[ "$READ_CAPACITY_UNITS" > 0 && "$WRITE_CAPACITY_UNITS" > 0 ]]
then
TABLE_DEFINITION="{\"AttributeDefinitions\":$ATTRIBUTE_DEFINITIONS,\"TableName\":\"$TABLE\",\"KeySchema\":$KEY_SCHEMA,\"ProvisionedThroughput\":{\"ReadCapacityUnits\":$READ_CAPACITY_UNITS,\"WriteCapacityUnits\":$WRITE_CAPACITY_UNITS}}"
else
TABLE_DEFINITION="{\"AttributeDefinitions\":$ATTRIBUTE_DEFINITIONS,\"TableName\":\"$TABLE\",\"KeySchema\":$KEY_SCHEMA,\"BillingMode\":$BILLING_MODE}"
fi
echo $TABLE_DEFINITION > create-table.json
aws dynamodb create-table --cli-input-json file://create-table.json --endpoint-url http://localhost:8000
echo "Querying table $TABLE from remote..."
DATA=$(aws dynamodb scan --table-name $TABLE --max-items $maxItems)
((index+=1))
echo "Saving remote table [$TABLE] contents to inserts.json file..."
echo $DATA | jq ".Items | {\"$TABLE\": [{\"PutRequest\": { \"Item\": .[]}}]}" > inserts.json
echo "Inserting rows to $TABLE in local database..."
aws dynamodb batch-write-item --request-items file://inserts.json --endpoint-url http://localhost:8000
nextToken=$(echo $DATA | jq '.NextToken')
while [[ "$nextToken" != "" && "$nextToken" != "null" ]]
do
echo "Querying table $TABLE from remote..."
DATA=$(aws dynamodb scan --table-name $TABLE --max-items $maxItems --starting-token $nextToken)
((index+=1))
echo "Saving remote table [$TABLE] contents to inserts.json file..."
echo $DATA | jq ".Items | {\"$TABLE\": [{\"PutRequest\": { \"Item\": .[]}}]}" > inserts.json
echo "Inserting rows to $TABLE in local database..."
aws dynamodb batch-write-item --request-items file://inserts.json --endpoint-url http://localhost:8000
nextToken=$(echo "$DATA" | jq '.NextToken')
done
done
echo "Deleting temporary files..."
rm -f table-description.json
rm -f create-table.json
rm -f inserts.json
echo "Database sync complete!"
此脚本循环遍历字符串数组,对于每个表名,它首先获取表的描述,并使用所需的最少参数构建一个创建 JSON 文件并创建表。然后它使用@Ivailo Bardarov 的其余逻辑来生成插入并将它们推送到创建的表中。最后它会清理生成的 JSON 文件。
请记住,我的目的只是为开发目的创建一个粗略的表副本(因此需要最少的参数)。
【讨论】:
我扩展了Valy dia 解决方案以允许仅使用 aws-cli 进行所有导出过程 | jq
aws dynamodb scan --max-items 3 --table-name <TABLE_NAME> \
| jq '{"<TABLE_NAME>": [.Items[] | {PutRequest: {Item: .}}]}' > data.json
aws dynamodb describe-table --table-name <TABLE_NAME> > describe.json | jq ' .Table | {"TableName": .TableName, "KeySchema": .KeySchema, "AttributeDefinitions": .AttributeDefinitions, "ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}}' > table-definition.json
aws dynamodb create-table --cli-input-json file://table-definition.json --endpoint-url http://localhost:8000 --region us-east-1
aws dynamodb batch-write-item --request-items file://data.json --endpoint-url http://localhost:8000
aws dynamodb scan --table-name <TABLE_NAME> --endpoint-url http://localhost:8000
【讨论】:
DynamoDB 现在具有原生导出到 S3 功能(JSON 和 Amazon Ion 格式)https://aws.amazon.com/blogs/aws/new-export-amazon-dynamodb-table-data-to-data-lake-amazon-s3/
【讨论】:
您可以在本地尝试此代码。但首先应该执行以下命令npm init -y && npm install aws-sdk
const AWS = require('aws-sdk');
AWS.config.update({region:'eu-central-1'});
const fs = require('fs');
const TABLE_NAME = "YOURTABLENAME"
const docClient = new AWS.DynamoDB.DocumentClient({
"sslEnabled": false,
"paramValidation": false,
"convertResponseTypes": false,
"convertEmptyValues": true
});
async function exportDB(){
let params = {
TableName: TABLE_NAME
};
let result = [];
let items;
do {
items = await docClient.scan(params).promise();
items.Items.forEach((item) => result.push(item));
params.ExclusiveStartKey = items.LastEvaluatedKey;
} while(typeof items.LastEvaluatedKey != "undefined");
await fs.writeFileSync("exported_data.json", JSON.stringify(result,null, 4));
console.info("Available count size:", result.length);
}
exportDB();
然后运行node index.js
希望对你有用
【讨论】:
对于非常大的数据集,运行连续(和并行)扫描可能是耗时且脆弱的过程(想象一下它在中间死亡)。幸运的是,AWS 最近为export your DynamoDB table data straight to S3 添加了一项功能。这可能是实现您想要的最简单的方法,因为它不需要您编写任何代码并运行任何任务/脚本,因为它是完全托管的。
完成后,您可以从 S3 下载它并使用 foreach record in file: documentClient.putItem 之类的逻辑或使用其他 tooling 之类的逻辑导入到本地 DynamoDB 实例。
【讨论】: