使用AWS DMS将数据从CSV(S3)迁移到DynamoDB

kqhtkvqz  于 2023-05-26  发布在  其他
关注(0)|答案(1)|浏览(172)

我在迁移一个表时遇到了一个问题,该表包含一个列中的JSON,该列应作为DyanmoDBMap插入。源数据的格式如下

<table border="1"><tr><th>userId</th><th>brandId</th><th>createdBy</th><th>modifiedBy</th><th>preferences</th><th>version</th></tr><tr><td>TU0001</td><td>TEST BRAND</td><td>{"channel":{"S":"website"},"date":{"S": "2022-06-13T08:16:26.300Z"},"userId":{"S":"TU0001"}}</td><td>{"channel":{"S":"website"},"date":{"S": "2022-06-13T015:26:10.200Z"},"userId":{"S":"TU0001"}}</td><td>{"Colour": {"S": "Red" },"Size":{"S": "XL" }}</td><td>1</td></tr></table>

DynamoDB中的表是sam结构,只是JSON值存储为MAP(dynamodb-map)。当我们使用DMS迁移时,它会将JSON作为字符串值插入,而不是像预期的那样插入MAP。
我定义了转换规则如下:

"attribute-mappings": [
      {
        "target-attribute-name": "userId",
        "attribute-type": "scalar",
        "attribute-sub-type": "string",
        "value": "${userId}"
      },
      {
        "target-attribute-name": "brandId",
        "attribute-type": "scalar",
        "attribute-sub-type": "string",
        "value": "${brandId}"
      },
      {
        "target-attribute-name": "createdBy",
        "attribute-type": "document",
        "attribute-sub-type": "dynamodb-map",
        "value": {
          "M": {
            "S": "${createdBy}"
          }
        }
      },
      {
        "target-attribute-name": "modifiedBy",
        "attribute-type": "document",
        "attribute-sub-type": "dynamodb-map",
        "value": {
          "M": {
            "S": "${modifiedBy}"
          }
        }
      },
      {
        "target-attribute-name": "preferences",
        "attribute-type": "document",
        "attribute-sub-type": "dynamodb-map",
        "value": {
          "M": {
            "S": "${preferences}"
          }
        }
      },
      {
        "target-attribute-name": "version",
        "attribute-type": "scalar",
        "attribute-sub-type": "number",
        "value": "${version}"
      }
    ]

我也尝试添加Map如下,它在DyanmoDB中添加了一个空Map。

"value": {
          "M": "${preferences}"
        }

希望有人能帮忙。

ma8fv8wu

ma8fv8wu1#

我认为DMS不支持将JSON字符串直接转换为DynamoMap。这里DMS将JSON数据作为字符串插入,而不是转换为DynamoDB Map或List类型。但您可以在迁移前或迁移后处理数据,以确保JSON数据正确解析到DyanamoDB Map中。

迁移前:

  • 处理源数据库中的数据,将JSON字符串转换为DMS可以处理的格式。
  • 编写一个脚本(JS/Python)从源代码中读取数据,将JSON转换为DynamoDBMap,然后写入DynamoDB。

    迁移后:
  • 从DynamoDB读取数据,然后将JSON字符串解析到Map中,然后写回DynamoDB。
  • 编写一个脚本,每次在DynamoDB表中迭代,检索字符串数据,将其转换为Map,然后更新DynamoDB中的项。

下面是Node.js与AWS SDK的“后处理”示例,可以在迁移后完成,您可以这样做:

const AWS = require('aws-sdk');

AWS.config.update({
  region: "your_region",
  // Add your credentials
});

const dynamodb = new AWS.DynamoDB.DocumentClient();
const tableName = 'your_table'; // replace with your table name

const scanAndProcessItems = async (startKey) => {
  try {
    const params = {
      TableName: tableName,
      ExclusiveStartKey: startKey
    };
    
    const data = await dynamodb.scan(params).promise();
    
    if (data.Items) {
      for (let item of data.Items) {
        // To parse JSON strings into DynamoDB Maps
        item.createdBy = JSON.parse(item.createdBy);
        item.modifiedBy = JSON.parse(item.modifiedBy);
        item.preferences = JSON.parse(item.preferences);
    
        // To write the item back to the table
        await dynamodb.put({ TableName: tableName, Item: item }).promise();
      }
    }
    
    // If there's more data to scan, it will recursively call this function
    if (data.LastEvaluatedKey) {
      await scanAndProcessItems(data.LastEvaluatedKey);
    }
    
  } catch (err) {
    console.error("An error occurred", err);
  }
};

scanAndProcessItems();

希望这对你有帮助。

相关问题