【问题标题】:Export data from DynamoDB从 DynamoDB 导出数据
【发布时间】:2013-09-24 15:14:46
【问题描述】:

是否可以以某种格式从 DynamoDB 表中导出数据?

具体的用例是我想从我的生产 dynamodb 数据库中导出数据并将该数据导入我的本地 dynamodb 实例,这样我的应用程序就可以使用本地数据副本而不是生产数据。

我使用link 作为 DynamoDB 的本地实例。

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb amazon-dynamodb-local


    【解决方案1】:

    有一个工具叫DynamoDBtoCSV

    可用于将所有数据导出到 CSV 文件。但是,相反,您将不得不构建自己的工具。我的建议是您将此功能添加到该工具中,并将其贡献给 Git 存储库。


    另一种方法是使用 AWS Data Pipeline 执行此任务(您将节省从 AWS 基础设施外部读取数据的所有成本)。方法类似:

    1. 构建输出管道
    2. 下载文件。
    3. 使用自定义阅读器对其进行解析。

    【讨论】:

    • 有趣的解决方案,有兴趣看看“自定义阅读器”,数据类型有很多噪音
    • 我想建议对这篇文章进行编辑,并提供一个运行它的示例,但它被 mods 拒绝了,谢谢 mods。无论如何,这是一种运行 DynamoDbToCsv 脚本的方法。 sudo npm install -g dynamodbexportcsv; DynamoDbExportCsv --table "yourtable" --awsregion "us-east-1" --columns "col1,col2,col3" --scans 8 --gzip; cat *.gz > combined.csv.gz
    【解决方案2】:

    试试我的简单 node.js 脚本dynamo-archive。它以 JSON 格式导出和导入。

    【讨论】:

    • 它几乎坏了——它可以导出但不能导入,它只会崩溃
    • @DenisMysenko,请提交工单,我们会修复
    【解决方案3】:

    Dynamo DB 现在提供了一种向 S3 导出和导入数据的方法 http://aws.amazon.com/about-aws/whats-new/2014/03/06/announcing-dynamodb-cross-region-export-import/

    【讨论】:

    • 这是一篇看起来已被 AWS Data Pipeline 取代的旧博客文章。 DynamoDB 中不再有导入/导出选项卡
    【解决方案4】:

    将其从 DynamoDB 界面导出到 S3。

    然后使用 sed 将其转换为 Json:

    sed -e 's/$/}/' -e $'s/\x02/,"/g' -e $'s/\x03/":/g' -e 's/^/{"/' <exported_table> > <exported_table>.json
    

    Source

    【讨论】:

    • 这拯救了我的一天!
    【解决方案5】:

    我发现当前用于简单导入/导出(包括通过 DynamoDB Local 往返)的最佳工具是这个 Python 脚本:

    https://github.com/bchew/dynamodump

    此脚本支持架构导出/导入以及数据导入/导出。它还使用批处理 API 进行高效操作。

    我已成功使用它从 DynamoDB 表中获取数据到本地 DynamoDB 以用于开发目的,它非常适合我的需求。

    【讨论】:

      【解决方案6】:

      对于那些宁愿使用 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);
      

      【讨论】:

      • 工作就像一个魅力。但是,必须在此库中实现对最后评估键的分页。
      【解决方案7】:

      在 DynamoDB Web 控制台中选择您的表,而不是 Actions -> Export/Import

      【讨论】:

      • 这只会导出您选择的记录。
      • 此技术还限制您最多导出 100 条记录。这对于小型数据集很好,但对于大型数据集,建议您使用管道导出到 S3。
      • 这种方法有严重的局限性。
      • 不好的方法,它并没有真正导出所有记录 - 只选择等于最大记录一页。
      【解决方案8】:

      我创建了一个实用程序类来帮助开发人员进行导出。如果您不想使用 AWS 的数据管道功能,可以使用此功能。 git hub repo 的链接是 -here

      【讨论】:

        【解决方案9】:

        如果您需要,您可以使用此方法将 Dynamo 数据转换为 JSON https://2json.net/dynamo

        【讨论】:

          【解决方案10】:

          在一个类似的用例中,我使用 DynamoDB Streams 来触发 AWS Lambda,它基本上写入了我的 DW 实例。您可能可以编写 Lambda 以将每个表更改写入您的非生产账户中的表。这样一来,您的 Devo 表也将保持与 Prod 非常接近。

          【讨论】:

            【解决方案11】:

            这会将所有项目导出为 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
            

            【讨论】:

            • 如果您选择“文本”选项并选中“DynamoDB Json”,您可以使用此格式在 AWS 控制台中一次创建一个项目。
            • 警告:如果 DynamoDB 包含转义字符(例如换行符),这在某些 shell 中可能不起作用
            • @Woodz 我在 bash 上测试过,你在哪个 shell 中遇到了错误?
            • @IvailoBardarov 不幸的是,bash 的行为(以及 bash 内置工具,如 echo - 请参阅 stackoverflow.com/questions/8467424/…)在操作系统之间并不一致,例如在 Intel MacOS 11.1 上,DynamoDB 记录包含转义换行符( \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
            【解决方案12】:

            这是一种使用aws clijq 从表中导出一些 数据(通常我们只想在本地获取产品数据的样本)的方法。 假设我们有一个名为 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。)。

            【讨论】:

            • 这一行在 Windows 中应该是什么样子?
            【解决方案13】:

            我使用了很棒的网络厨师网站...https://gchq.github.io/CyberChef

            使用csv to json 工具。

            【讨论】:

              【解决方案14】:

              我认为我的回答与 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 上执行,我没有测试,所以这里就不加了。

              【讨论】:

              • 我在 Windows 上测试过,这里有一个示例:aws dynamodb scan --table-name=TableA > export.json --region=us-east-1
              • 感谢您的确认
              【解决方案15】:

              扩展@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 文件。

              请记住,我的目的只是为开发目的创建一个粗略的表副本(因此需要最少的参数)。

              【讨论】:

                【解决方案16】:

                我扩展了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
                

                【讨论】:

                • Windows 版本 aws dynamodb describe-table --no-verify-ssl --table-name | jq ".Table | {\"TableName\": .TableName, \"KeySchema\": .KeySchema, \"AttributeDefinitions\": .AttributeDefinitions, \"ProvisionedThroughput\": { \"ReadCapacityUnits\": 5, \" WriteCapacityUnits\": 5}, \"GlobalSecondaryIndexes\": {\"IndexName\": .IndexName, \"KeySchema\": .KeySchema, \"Projection\": .Projection, \"ProvisionedThroughput\": { \" ReadCapacityUnits\": 5, \"WriteCapacityUnits\": 5 }}}"
                【解决方案17】:

                DynamoDB 现在具有原生导出到 S3 功能(JSON 和 Amazon Ion 格式)https://aws.amazon.com/blogs/aws/new-export-amazon-dynamodb-table-data-to-data-lake-amazon-s3/

                【讨论】:

                  【解决方案18】:

                  您可以在本地尝试此代码。但首先应该执行以下命令npm init -y &amp;&amp; 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

                  希望对你有用

                  【讨论】:

                    【解决方案19】:

                    对于非常大的数据集,运行连续(和并行)扫描可能是耗时且脆弱的过程(想象一下它在中间死亡)。幸运的是,AWS 最近为export your DynamoDB table data straight to S3 添加了一项功能。这可能是实现您想要的最简单的方法,因为它不需要您编写任何代码并运行任何任务/脚本,因为它是完全托管的。

                    完成后,您可以从 S3 下载它并使用 foreach record in file: documentClient.putItem 之类的逻辑或使用其他 tooling 之类的逻辑导入到本地 DynamoDB 实例。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2019-08-28
                      • 2016-07-27
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多