I'm using Postgres with Sequelize and I need to update an existing ForeignKey
Constraint with onDelete = Cascade
.
I have updated my model, but the migration file comes up as a skeleton. I haven't found a way to update this constraint.
My model file:
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"});
};
My migration file:
module.exports = {
up: (queryInterface, Sequelize) => {
// How can I update a FK constraint??
},
down: (queryInterface, Sequelize) => {
// How can I undo an FK update constraint??
}
};
Any ideas on how to make this migration?
Sequelize association methods also accept an options object that you can use to configure the details of the association. For example, you can change the foreign key name on the table by adding the foreignKey property: User. hasOne(Invoice, { foreignKey: "invoice_creator", // UserId -> invoice_creator });
As shown above, the foreignKey option accepts a string or an object. When receiving an object, this object will be used as the definition for the column just like it would do in a standard sequelize.define call. Therefore, specifying options such as type , allowNull , defaultValue , etc, just work.
Constraints are the rules that we define on the level of SQL. For example, if one attribute is supposed to be unique then this will be handled on the level of SQL. If a constraint check fails then Sequelize will forward the error message sent by the database.
I found it simplest to first remove the existing constraint and then add it back with onDelete. Sequelize has queryInterface.removeConstraint
and queryInterface.addConstraint
methods for this.
Here is a contrived example:
'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;
}
},
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With