将迁移更改列序列化为 FK,然后撤消失败
Sequelize migration changing column to be FK and then undo failing
我正在尝试创建迁移文件以将 changeColumn 设为字符串(来自枚举)并引用其他 table。
const enumStatus = ['PENDING', 'SUCCESSFUL', 'FAILED', 'FAILED_LAST_VALUE_MISSING', 'FAILED_LAST_DATE_MISSING', 'FAILED_OLD_LAST_DATE'];
module.exports = {
up: async(queryInterface, Sequelize) => {
return Promise.all([
queryInterface.changeColumn('MeasurementTestResults', 'status', {
type: Sequelize.STRING,
allowNull: false
}), queryInterface.addConstraint('MeasurementTestResults', {
fields: ['status'],
type: 'foreign key',
name: 'statusFk',
references: {
table: 'MeasurementTestResultStatusEnums',
field: 'code'
},
onDelete: 'cascade',
onUpdate: 'cascade'
})
]);
},
down: async(queryInterface, Sequelize) => {
return Promise.all([
queryInterface.removeConstraint('MeasurementTestResults', 'statusFk'),
queryInterface.changeColumn('MeasurementTestResults', 'status', {
type: Sequelize.ENUM(...enumStatus),
allowNull: false
})
]);
}
};
db:migrate 运行 完美无缺,但是当我尝试调用 db:migrate:undo 时它会乱序执行命令?
== 20201217194748-measurementTestResult_changeColumn_status: reverting =======
Executing (default): SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRA
INTS WHERE table_name='MeasurementTestResults' AND constraint_name = 'statusFk' AND TABLE_SCHEMA = 'iot_crcm_application_data1';
Executing (default): ALTER TABLE `MeasurementTestResults` CHANGE `status` `status` ENUM('PENDING', 'SUCCESSFUL', 'FAILED', 'FAILED_LAST_VALUE_MISSING', 'FAILED_LAST_DATE_MISSING', 'FAILED_OLD_LAST_DATE') NOT NULL;
Executing (default): ALTER TABLE `MeasurementTestResults`
DROP FOREIGN KEY `statusFk`;
ERROR: (conn=143438, no: 1832, SQLState: HY000) Cannot change column 'status': used in a foreign key constraint 'statusFk'
sql: ALTER TABLE `MeasurementTestResults` CHANGE `status` `status` ENUM('PENDING', 'SUCCESSFUL', 'FAILED', 'FAILED_LAST_VALUE_MISSING', 'FAILED_LAST_DATE_MISSING', 'FAILED_OLD_LAST_DATE') NOT NULL; - parameters:[]
然后当我尝试从 down 脚本中删除 queryInterface.removeConstraint('MeasurementTestResults', 'statusFk'),
这一行时,它起作用了,但是在我尝试之前没有错误...
不要尝试使用 Promise.all
并行执行相互依赖的结构更改。你最好一一称呼他们:
await queryInterface.removeConstraint('MeasurementTestResults', 'statusFk')
await queryInterface.changeColumn('MeasurementTestResults', 'status', {
type: Sequelize.ENUM(...enumStatus),
allowNull: false
})
up
方法也是如此。
我正在尝试创建迁移文件以将 changeColumn 设为字符串(来自枚举)并引用其他 table。
const enumStatus = ['PENDING', 'SUCCESSFUL', 'FAILED', 'FAILED_LAST_VALUE_MISSING', 'FAILED_LAST_DATE_MISSING', 'FAILED_OLD_LAST_DATE'];
module.exports = {
up: async(queryInterface, Sequelize) => {
return Promise.all([
queryInterface.changeColumn('MeasurementTestResults', 'status', {
type: Sequelize.STRING,
allowNull: false
}), queryInterface.addConstraint('MeasurementTestResults', {
fields: ['status'],
type: 'foreign key',
name: 'statusFk',
references: {
table: 'MeasurementTestResultStatusEnums',
field: 'code'
},
onDelete: 'cascade',
onUpdate: 'cascade'
})
]);
},
down: async(queryInterface, Sequelize) => {
return Promise.all([
queryInterface.removeConstraint('MeasurementTestResults', 'statusFk'),
queryInterface.changeColumn('MeasurementTestResults', 'status', {
type: Sequelize.ENUM(...enumStatus),
allowNull: false
})
]);
}
};
db:migrate 运行 完美无缺,但是当我尝试调用 db:migrate:undo 时它会乱序执行命令?
== 20201217194748-measurementTestResult_changeColumn_status: reverting =======
Executing (default): SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRA
INTS WHERE table_name='MeasurementTestResults' AND constraint_name = 'statusFk' AND TABLE_SCHEMA = 'iot_crcm_application_data1';
Executing (default): ALTER TABLE `MeasurementTestResults` CHANGE `status` `status` ENUM('PENDING', 'SUCCESSFUL', 'FAILED', 'FAILED_LAST_VALUE_MISSING', 'FAILED_LAST_DATE_MISSING', 'FAILED_OLD_LAST_DATE') NOT NULL;
Executing (default): ALTER TABLE `MeasurementTestResults`
DROP FOREIGN KEY `statusFk`;
ERROR: (conn=143438, no: 1832, SQLState: HY000) Cannot change column 'status': used in a foreign key constraint 'statusFk'
sql: ALTER TABLE `MeasurementTestResults` CHANGE `status` `status` ENUM('PENDING', 'SUCCESSFUL', 'FAILED', 'FAILED_LAST_VALUE_MISSING', 'FAILED_LAST_DATE_MISSING', 'FAILED_OLD_LAST_DATE') NOT NULL; - parameters:[]
然后当我尝试从 down 脚本中删除 queryInterface.removeConstraint('MeasurementTestResults', 'statusFk'),
这一行时,它起作用了,但是在我尝试之前没有错误...
不要尝试使用 Promise.all
并行执行相互依赖的结构更改。你最好一一称呼他们:
await queryInterface.removeConstraint('MeasurementTestResults', 'statusFk')
await queryInterface.changeColumn('MeasurementTestResults', 'status', {
type: Sequelize.ENUM(...enumStatus),
allowNull: false
})
up
方法也是如此。