问题
I am using the sequelize ORM in my nodejs app and it seems that it drops table in the wrong order when I sequelize.sync({force: true})
For example, with:
var StationEntity = sequelize.define('Station', {
id: { type: Sequelize.INTEGER, primaryKey: true, allowNull: false},
name: { type: Sequelize.STRING, allowNull: false}
})
var StationSnapshotEntity = sequelize.define('StationSnapshot', {
id: { type: Sequelize.BIGINT, autoIncrement: true, primaryKey: true},
snapshotTimestamp: { type: Sequelize.BIGINT, allowNull: false}
})
StationEntity.hasMany(StationSnapshotEntity, {as: 'Snapshots', foreignKeyConstraint: true, allowNull: false})
I get the following logs after sequelize.sync({force: true}):
Executing: DROP TABLE IF EXISTS `Stations`;
Executing: DROP TABLE IF EXISTS `StationSnapshots`;
Executing: CREATE TABLE IF NOT EXISTS `StationSnapshots` (`id` BIGINT auto_increment , `snapshotTimestamp` BIGINT NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `StationId` INTEGER, PRIMARY KEY (`id`), FOREIGN KEY (`StationId`) REFERENCES `Stations` (`id`)) ENGINE=InnoDB;
Error: ER_ROW_IS_REFERENCED: Cannot delete or update a parent row: a foreign key constraint fails
Seems to be dropping tables in the wrong order.
回答1:
Same answer as Guest but without external requirements.
db.query('SET FOREIGN_KEY_CHECKS = 0')
.then(function(){
return db.sync({ force: true });
})
.then(function(){
return db.query('SET FOREIGN_KEY_CHECKS = 1')
})
.then(function(){
console.log('Database synchronised.');
}, function(err){
console.log(err);
});
回答2:
Disable foreign key checks before doing sequelize.sync({force: true})
For example:
async.series([
function(callback) {
sequelize.query("SET FOREIGN_KEY_CHECKS = 0").complete(callback);
},
function(callback) {
sequelize.sync({force: true}).complete(callback);
},
function(callback) {
sequelize.query("SET FOREIGN_KEY_CHECKS = 1").complete(callback);
}]
, callback);
回答3:
This worked for me:
sequelize.query('SET FOREIGN_KEY_CHECKS = 0').success(function() {
sequelize
.sync({
force: true
}).success(function() {
sequelize.query('SET FOREIGN_KEY_CHECKS = 1').success(function() {
console.log('Database synchronised.');
});
}).error(function(err) {
console.log(err);
});;
}).error(function(ee) {
console.log(err);
});
回答4:
This worked for my models and relationship.
/* the models in the array are declared on the basis of relationships */
var models = [
'User',
'State',
'Party',
'Politician',
'Constituency',
'Award',
'Comment',
'Favorite',
'Rating'
];
models.forEach(function(model) {
//need to drop things to make sure the order is maintained while droping tables...
module.exports[model] = sequelize.import(__dirname + '/' + model);
});
/*** setup relationships ***/
(function(m) {
m.Award.belongsTo(m.Politician, {foreignKey: 'award_politician_id',
as: 'politician_id',foreignKeyConstraint:true});
m.Politician.hasMany(m.Award, {foreignKey: 'award_politician_id',foreignKeyConstraint:true});
m.Comment.belongsTo(m.User, {foreignKey: 'comment_user_id',
as: 'user_id',foreignKeyConstraint:true});
m.Comment.belongsTo(m.Politician, {foreignKey: 'comment_politician_id',
foreignKeyConstraint:true});
m.Politician.hasMany(m.Comment, {foreignKey: 'comment_politician_id',
foreignKeyConstraint:true});
m.User.hasMany(m.Comment, {foreignKey: 'comment_user_id',
foreignKeyConstraint:true});
m.Favorite.belongsTo(m.User, {foreignKey: 'favorite_user_id',
as: 'user_id',foreignKeyConstraint:true});
m.Favorite.belongsTo(m.Politician, {foreignKey: 'favorite_politician_id',
as: 'politician_id',foreignKeyConstraint:true});
m.Politician.hasMany(m.Favorite,{foreignKey: 'favorite_politician_id',
foreignKeyConstraint:true});
m.User.hasMany(m.Favorite, {foreignKey: 'favorite_user_id',
foreignKeyConstraint:true});
m.Rating.belongsTo(m.User, {foreignKey: 'rating_user_id',
as: 'user_id',foreignKeyConstraint:true});
m.Rating.belongsTo(m.Politician, {foreignKey: 'rating_politician_id',
as: 'user_id',foreignKeyConstraint:true});
m.Politician.hasMany(m.Rating, {foreignKey: 'rating_politician_id',
foreignKeyConstraint:true}
);
m.User.hasMany(m.Rating, {foreignKey: 'rating_user_id',
foreignKeyConstraint:true}
);
m.Constituency.belongsTo(m.State, {foreignKey: 'constituency_state_id',
as: 'state_id',foreignKeyConstraint:true});
m.State.hasMany(m.Constituency,{foreignKey: 'constituency_state_id', foreignKeyConstraint:true});
m.Politician.belongsTo(m.Party, { foreignKey: 'politician_party_id',
as: 'party_id',
foreignKeyConstraint:true});
m.Party.hasMany(m.Politician, {foreignKey: 'politician_party_id', foreignKeyConstraint:true});
// m.User.drop();
//
// sequelize.sync();
})(module.exports);
/** drop existing relationships manually in reverse order**/
models.reverse().forEach(function(model) {
sequelize.import(__dirname + '/' + model).drop().success(function(){
console.log("success model:" + model);
}).error(function(error){
console.log("model:" + model + " error:" + error);
});
});
/** sync **/
sequelize.sync();
来源:https://stackoverflow.com/questions/17822663/sequelize-drop-table-in-wrong-order