我正在将Postgres与Sequelize结合使用,我需要用ForeignKey
更新现有的onDelete = Cascade
约束。
我已经更新了我的模型,但是迁移文件却是骨架。我还没有找到更新此约束的方法。
我的模型文件:
export const Property = sequelize.define<PropertyModel, PropertyAttribute>('property', {
id: {
type: Sequelize.UUID,
primaryKey: true,
defaultValue: Sequelize.UUIDV4,
allowNull: false
},
name: Sequelize.STRING,
status: {
type: Sequelize.BOOLEAN,
defaultValue: true
},
publishedAt: Sequelize.DATE
});
Property.associate = models => {
Property.belongsTo(models.User, {
foreignKey: { allowNull: false },
allowNull: false
});
Property.hasMany(
models.PropertyService, {onDelete: "cascade"});
Property.hasMany(
models.Visitor, {onDelete: "cascade"});
};
我的迁移文件:
module.exports = {
up: (queryInterface, Sequelize) => {
// How can I update a FK constraint??
},
down: (queryInterface, Sequelize) => {
// How can I undo an FK update constraint??
}
};
关于如何进行此迁移的任何想法?
答案 0 :(得分:2)
我不认为可以通过标准的Sequelize迁移queryInterface来处理约束,因此我过去实现此目标的方法是在PostgreSQL上运行原始ALTER TABLE
查询以删除并重新执行-创建FOREIGN KEY
约束,例如:
const tableName = 'property';
const constraintName = 'property_property_service_id_fkey';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.query(`alter table "${tableName}" drop constraint "${constraintName}"`)
.then(() => queryInterface.sequelize.query(
`alter table "${tableName}"
add constraint "${constraintName}" foreign key("property_service_id") references "property_service" ("id")
on delete cascade`
));
},
down: (queryInterface, Sequelize) => {
return queryInterface.sequelize.query(`alter table "${tableName}" drop constraint "${constraintName}"`)
.then(() => queryInterface.sequelize.query(
`alter table "${tableName}"\
add constraint "${constraintName}" foreign key("property_service_id") references "property_service" ("id")
on delete no action`
));
},
};
请注意,我已经对您的表,字段和约束名称做了一些假设,因此您可能需要根据Sequelize配置设置对其中一些进行调整。
答案 1 :(得分:2)
我发现最简单的方法是先删除现有约束,然后使用onDelete将其重新添加。为此,Sequelize具有queryInterface.removeConstraint
和queryInterface.addConstraint
方法。
这是一个人为的例子:
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.removeConstraint(
'users',
'users_address_id_fkey',
{ transaction }
);
await queryInterface.addConstraint('users', ['address_id'], {
type: 'foreign key',
name: 'users_address_id_fkey',
references: {
table: 'addresses',
field: 'id',
},
onDelete: 'CASCADE',
transaction
});
return transaction.commit();
} catch (error) {
await transaction.rollback();
throw error;
}
},
down: async (queryInterface, Sequelize) => {
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.removeConstraint(
'users',
'users_address_id_fkey',
{ transaction }
);
await queryInterface.addConstraint('users', ['address_id'], {
type: 'foreign key',
name: 'users_address_id_fkey',
references: {
table: 'addresses',
field: 'id',
},
transaction
});
return transaction.commit();
} catch (error) {
await transaction.rollback();
throw error;
}
},
};