布尔列的 AWS DMS 问题
AWS DMS Issue with boolean column
我正在尝试使用 DMS 启用复制,将 Aurora mySQL 实例用作源,将 Redshift 实例用作目标。
复制在布尔列上失败。我已在 mySQL 实例上将布尔列声明为 BIT(1)。
根据文档,mySQL 中的布尔列应定义为 BIT:
https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Source.MySQL.html#CHAP_Source.MySQL.DataTypes
如果我删除布尔值列,它就会起作用。我还尝试将列定义为布尔值。那也没用。
这是我遇到的错误:
2018-08-26T16:59:19 [TARGET_APPLY ]E: RetCode: SQL_ERROR SqlState:
42804 NativeError: 30 Message: [Amazon][Amazon Redshift] (30) Error
occurred while trying to execute a query: [SQLState 42804] ERROR:
column "state" is of type boolean but expression is of type character
varying, HINT: You will need to rewrite or cast the expression.
[1022502] (ar_odbc_stmt.c:4428)
原来是DMS的bug。这仅在正在进行的复制期间发生,而不是在满载时发生。在从 Aurora MySql 复制到 Redshift 期间,布尔值被强制转换为 Varchar,从而导致上述错误。
我遇到了同样的问题,但我迁移了我的基地,所以我用 post-script 解决了这个问题,这可能对你有帮助。此外,您可以使用 DMS 事件通知短信,然后调用 lambda 来实现。
仅使用节点 运行 file.js init()
const AWS = require("aws-sdk");
AWS.config.update({
region: "us-east-1"
});
const documentClient = new AWS.DynamoDB.DocumentClient();
let invalidList = [];
const TableName = 'TableName';
const params = {
TableName: TableName,
};
module.exports.init = function () {
console.log("Start Conversions of Details Booleans")
documentClient.scan(params, function(err, data) {
if (err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("Scan succeeded.");
// By default scan retrieves at max 1 mb of data
if (typeof data.LastEvaluatedKey != "undefined") {
console.log("Scanning for more...");
params.ExclusiveStartKey = data.LastEvaluatedKey;
documentClient.scan(params, onScan);
}
invalidList = getinvalidList(data);
if(invalidList.length == 0) {
console.log("All data is aready migrated");
return;
}
updateList(invalidList);
}
});
};
function getinvalidList(list) {
return list.Items.reduce((invalidList, item) => {
if (item) {
const variable = (item.variable && item.variable != undefined) ? item.variable : '0';
if (isNotBoolean(variable)) {
invalidList.push(item);
}
}
return invalidList;
}, []);
}
function updateList(list) {
list.forEach(item => {
var params = {
TableName: TableName,
Key: {
"id": item.id,
},
UpdateExpression: "set variable = :variable",
ExpressionAttributeValues: {
":variable": newValue(item.variable),
},
ReturnValues: "UPDATED_NEW"
};
documentClient.update(params, function(err, data) {
if (err) console.log(err);
else console.log(data);
},
)
});
}
function newValue(variable) {
return isNotBoolean(variable) ? !!+variable : variable
}
function isNotBoolean(variable) {
return (typeof variable !== 'boolean')
}
我正在尝试使用 DMS 启用复制,将 Aurora mySQL 实例用作源,将 Redshift 实例用作目标。 复制在布尔列上失败。我已在 mySQL 实例上将布尔列声明为 BIT(1)。 根据文档,mySQL 中的布尔列应定义为 BIT:
https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Source.MySQL.html#CHAP_Source.MySQL.DataTypes
如果我删除布尔值列,它就会起作用。我还尝试将列定义为布尔值。那也没用。
这是我遇到的错误:
2018-08-26T16:59:19 [TARGET_APPLY ]E: RetCode: SQL_ERROR SqlState: 42804 NativeError: 30 Message: [Amazon][Amazon Redshift] (30) Error occurred while trying to execute a query: [SQLState 42804] ERROR: column "state" is of type boolean but expression is of type character varying, HINT: You will need to rewrite or cast the expression. [1022502] (ar_odbc_stmt.c:4428)
原来是DMS的bug。这仅在正在进行的复制期间发生,而不是在满载时发生。在从 Aurora MySql 复制到 Redshift 期间,布尔值被强制转换为 Varchar,从而导致上述错误。
我遇到了同样的问题,但我迁移了我的基地,所以我用 post-script 解决了这个问题,这可能对你有帮助。此外,您可以使用 DMS 事件通知短信,然后调用 lambda 来实现。
仅使用节点 运行 file.js init()
const AWS = require("aws-sdk");
AWS.config.update({
region: "us-east-1"
});
const documentClient = new AWS.DynamoDB.DocumentClient();
let invalidList = [];
const TableName = 'TableName';
const params = {
TableName: TableName,
};
module.exports.init = function () {
console.log("Start Conversions of Details Booleans")
documentClient.scan(params, function(err, data) {
if (err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("Scan succeeded.");
// By default scan retrieves at max 1 mb of data
if (typeof data.LastEvaluatedKey != "undefined") {
console.log("Scanning for more...");
params.ExclusiveStartKey = data.LastEvaluatedKey;
documentClient.scan(params, onScan);
}
invalidList = getinvalidList(data);
if(invalidList.length == 0) {
console.log("All data is aready migrated");
return;
}
updateList(invalidList);
}
});
};
function getinvalidList(list) {
return list.Items.reduce((invalidList, item) => {
if (item) {
const variable = (item.variable && item.variable != undefined) ? item.variable : '0';
if (isNotBoolean(variable)) {
invalidList.push(item);
}
}
return invalidList;
}, []);
}
function updateList(list) {
list.forEach(item => {
var params = {
TableName: TableName,
Key: {
"id": item.id,
},
UpdateExpression: "set variable = :variable",
ExpressionAttributeValues: {
":variable": newValue(item.variable),
},
ReturnValues: "UPDATED_NEW"
};
documentClient.update(params, function(err, data) {
if (err) console.log(err);
else console.log(data);
},
)
});
}
function newValue(variable) {
return isNotBoolean(variable) ? !!+variable : variable
}
function isNotBoolean(variable) {
return (typeof variable !== 'boolean')
}