【发布时间】:2020-05-25 13:32:17
【问题描述】:
好的,我正在尝试一些不同的 ORM,目前正在开发 Sequelize。我已经定义了两个模型,asset 和asset_category,其中每个资产都有一个与asset_category 的外键关系。都好! 现在,我想从使用自动增量 id 更改为 uuid,因为它对安全性更好。所以我在数据库中有数据并编写了以下(超长!)迁移:
up: (queryInterface, Sequelize) => {
return queryInterface
.addColumn("asset_categories", "uuid", {
// Add uuid column
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
})
.then(_ => {
return queryInterface.sequelize.query(
// Fill uuid column
`
UPDATE asset_categories SET uuid=uuid()
`,
);
})
.then(_ => {
return queryInterface.addColumn("assets", "category_uuid", {
// Add assets reference uuid column
type: Sequelize.UUID,
allowNull: false,
});
})
.then(_ => {
return queryInterface.sequelize.query(
// Fill assets reference uuid column
`
UPDATE assets
SET category_uuid= (SELECT ac.uuid FROM asset_categories ac WHERE ac.id = assets.category_id)
`,
);
})
.then(_ => {
// Remove assets category_id column
return queryInterface.removeColumn("assets", "category_id");
})
.then(_ => {
// Remove asset_categories id column
return queryInterface.removeColumn("asset_categories", "id");
})
.then(_ => {
// Rename asset_categories uuid to id
return queryInterface.renameColumn("asset_categories", "uuid", "id");
})
.then(_ => {
// Rename assets category_uuid to category_id
return queryInterface.renameColumn(
"assets",
"category_uuid",
"category_id",
);
})
.then(_ => {
return queryInterface.changeColumn("asset_categories", "id", {
// Add primary key to asset_categories id field
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
primaryKey: true,
});
})
.then(_ => {
// Add index to asset_categories id field
return queryInterface.addIndex("asset_categories", ["id"]);
})
.then(_ => {
// Add index to assets category_id field
return queryInterface.addIndex("assets", ["category_id"]);
});
还有:
up: (queryInterface, Sequelize) => {
// Add uuid column
return queryInterface
.addColumn("assets", "uuid", {
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
primaryKey: false,
})
.then(_ => {
// Fill uuid column
return queryInterface.sequelize.query(
`
UPDATE assets SET uuid=uuid()
`,
);
})
.then(_ => {
// Remove assets id column
return queryInterface.removeColumn("assets", "id");
})
.then(_ => {
// Rename assets uuid to id
return queryInterface.renameColumn("assets", "uuid", "id");
})
.then(_ => {
// Add primary key to uuid column
return queryInterface.changeColumn("assets", "id", {
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
primaryKey: true,
});
})
.then(_ => {
// add foreign key on assets category_id
return queryInterface.changeColumn("assets", "category_id", {
type: Sequelize.UUID,
allowNull: false,
references: {
model: {
tableName: "asset_categories",
},
key: "id",
},
});
});
问题是我在最后一步出现错误:
ERROR: Referencing column 'category_id' and referenced column 'id' in foreign key constraint 'assets_ibfk_1' are incompatible.
似乎在所有这些步骤中,asset_category.id 更改为
id char(36) 字符集 utf8mb4 整理 utf8mb4_bin 非空,
虽然asset.category_id 是
category_id char(36) 整理 utf8mb4_general_ci 非空,
我假设这是我无法添加外键的原因,因为列不完全相同。
对于初学者:这是怎么发生的?是什么导致列获得不同的字符集或整理?还有:有没有更好的方法来处理这种迁移,因为与使用 Ruby on Rails + Active Record 相比,这似乎完全是垃圾......
【问题讨论】:
标签: mysql node.js orm sequelize.js utf8mb4