续集 Postgresql 没有强制外部约束



我有这些模型。(门票和活动(。该活动有许多门票,一张门票属于一个活动。

型号/ticket.js

'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Ticket extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
Ticket.belongsTo(models.Event, {
foreignKey: "event_id",
as: "event"
})
Ticket.hasMany(models.Order, {
foreignKey: "ticket_id",
as: "orders"
})
}
};
Ticket.init({
ticket_type: {
type: DataTypes.STRING, allowNull: false, validate: { notNull: { args: true, msg: "Ticket type is required" } }
},
event_id: {
type: DataTypes.INTEGER, allowNull: false, validate: { notNull: { args: true, msg: "event_id is required" } }
},
ticket_quota: {
type: DataTypes.INTEGER, default: 0
},
ticket_price: {
type: DataTypes.FLOAT, default: 1
}
}, {
sequelize,
modelName: 'Ticket',
});
return Ticket;
};

models/event.js

'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Event extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
Event.hasMany(models.Ticket, {
foreignKey: "event_id",
as: "tickets"
})
}
};
Event.init({
event_name: {
type: DataTypes.STRING, allowNull: false, validate: { notNull: { args: true, msg: "Event name is required" } }
},
event_date: {
type: DataTypes.DATE, allowNull: false, validate: { notNull: { args: true, msg: "Event Date is required" } }
},
event_location: {
type: DataTypes.STRING, allowNull: false, validate: { notNull: { args: true, msg: "Event location is required" } }
},
event_description: DataTypes.STRING
}, {
sequelize,
modelName: 'Event',
});
return Event;
};

从这里可以看出,门票与活动相关。问题是当我尝试插入事件表中不存在的event_id的票证时。尽管存在约束,它仍然插入。

有人知道哪里出了问题以及如何解决吗?

提前谢谢。

您需要在关联中使用allowNull: false

// define association here
Event.hasMany(models.Ticket, {
foreignKey: "event_id",
as: "tickets",
allowNull: false,
})

最后的解决方案:

最终迁移:

'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
/**
* Add altering commands here.
*
* Example:
* await queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
queryInterface.removeColumn("Tickets",'event_id')
queryInterface.removeColumn("Orders",'ticket_id')
queryInterface.removeColumn("Orders",'user_id')
queryInterface.addColumn(
'Tickets', // name of Source model
'event_id', // name of the key we're adding 
{
type: Sequelize.INTEGER,
references: {
model: 'Events', // name of Target model
key: 'id', // key in Target model that we're referencing
},
allowNull: false,
validate: { notNull: { args: true, msg: "event_id is required" }},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}
);
queryInterface.addColumn(
'Orders', // name of Source model
'user_id', // name of the key we're adding 
{
type: Sequelize.INTEGER,
references: {
model: 'Users', // name of Target model
key: 'id', // key in Target model that we're referencing
},
allowNull: false,
validate: { notNull: { args: true, msg: "user_id is required" }},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}
);
return queryInterface.addColumn(
'Orders', // name of Source model
'ticket_id', // name of the key we're adding 
{
type: Sequelize.INTEGER,
references: {
model: 'Tickets', // name of Target model
key: 'id', // key in Target model that we're referencing
},
allowNull: false,
validate: { notNull: { args: true, msg: "ticket_id is required" }},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}
);
},
down: async (queryInterface, Sequelize) => {
/**
* Add reverting commands here.
*
* Example:
* await queryInterface.dropTable('users');
*/
queryInterface.removeColumn("Tickets",'event_id')
queryInterface.removeColumn("Orders",'ticket_id')
queryInterface.removeColumn("Orders",'user_id')
queryInterface.addColumn(
'Tickets', // name of Source model
'event_id', // name of the key we're adding 
{
type: Sequelize.INTEGER,
allowNull: false,
validate: { notNull: { args: true, msg: "event_id is required" }},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}
);
queryInterface.addColumn(
'Orders', // name of Source model
'user_id', // name of the key we're adding 
{
type: Sequelize.INTEGER,
allowNull: false,
validate: { notNull: { args: true, msg: "user_id is required" }},
}
);
return queryInterface.addColumn(
'Orders', // name of Source model
'ticket_id', // name of the key we're adding 
{
type: Sequelize.INTEGER,
allowNull: false,
validate: { notNull: { args: true, msg: "ticket_id is required"}}
}
);
}
};

最新更新