次の列を持つProduct
テーブルと[id, name, CategoryId]
および[id, name]
を持つCategory
テーブルがあります
製品モデル:-
module.exports = function(sequelize, DataTypes) {
var Product = sequelize.define('Product', {
name: DataTypes.STRING
}, {
associate: function(models) {
Product.belongsTo(models.Category);
}
});
return Product
}
カテゴリモデル:-
module.exports = function(sequelize, DataTypes) {
var Category = sequelize.define('Category', {
name: { type: DataTypes.STRING, allowNull: false }
}, {
associate: function(models) {
Category.hasMany(models.Product, { onDelete: 'cascade' });
}
});
return Category
}
カテゴリを削除すると、カテゴリに関連付けられている対応する製品のみが削除されます。なぜこれが起こっているのか分かりませんか?
更新:Sequelizeバージョンsequelize 1.7.0
================================================= =============================Answer(これをどのように修正しましたか?):-
Add Foreign Key Constraint
からAlter
までがmigration
のopen bug であるため、sequelize
コマンドを使用してデータベースに制約を追加することでこれを達成しました。
ALTER TABLE "Products"
ADD CONSTRAINT "Products_CategoryId_fkey" FOREIGN KEY ("CategoryId")
REFERENCES "Categories" (id) MATCH SIMPLE
ON DELETE CASCADE
OnDeleteは、製品モデルではなくカテゴリモデルに配置することになっていると思います。
module.exports = function(sequelize, DataTypes) {
var Category = sequelize.define('Category', {
name: { type: DataTypes.STRING, allowNull: false }
}, {
associate: function(models) {
Category.hasMany(models.Product, { onDelete: 'cascade' });
}
});
return Category
}
"sequelize": "^ 3.5.1"の時点で、belongsTo
宣言にonDelete='CASCADE'
を入れた場合にのみ機能します。これは、あなたのケースではProduct
モデルです。これはドキュメントと矛盾します: http://sequelize.readthedocs.org/en/latest/api/associations/index.html?highlight=onDelete#hasmanytarget-options
この質問をご覧ください: Sequelize onDelete not working
私はSequelize 4.38.0を使用しています。
onDelete: 'CASCADE'
は、関連付けの定義だけでなく、移行ファイルにも含まれます。
// in models/user.js
User.associate = models => {
User.belongsTo(models.Organization, {
foreignKey: { name: 'organizationId', allowNull: true },
onDelete: 'CASCADE',
})
}
// in migrations/create-users.js
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Users', {
// other fields...
organizationId: {
type: Sequelize.INTEGER,
allowNull: true,
onDelete: 'CASCADE',
references: {
model: 'Organizations',
key: 'id',
as: 'organizationId',
},
},
})
},
私はついに、妄想のためにそれが私のために働いていないと考えました。 Sequelizeはcascade
を処理せず、代わりにMySQLカスケード削除を行います。そうは言っても、テーブルに偏執病を使用すると、レコードがテーブルから実際に削除されないため、カスケードは発生しません。
ここでの問題は、foreign key
のCONSTRAINT
が欠落している移行スクリプトが生成されることです。
私はまだ問題イベントをフォローしています 公式ドキュメント for { onDelete: 'cascade', hooks: true }
。
私のソリューションは次のとおりです。
手順1:通常どおり移行ファイルを作成しますが、foreign key
はまだ作成しません。定義したassociate
を覚えていた
Product.belongsTo(models.Category);
Category.hasMany(models.Product);
ステップ2:foreign key
列をテーブルに追加する移行スクリプトを作成します。
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.addColumn(
'Product', // name of Source model
'categoryId', // name of the key we're adding
{
type: Sequelize.INTEGER,
references: {
model: 'Category', // name of Target model
key: 'id', // key in Target model that we're referencing
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
}
);
},
down: (queryInterface, Sequelize) => {
return queryInterface.removeColumn(
'Product', // name of Source model
'categoryId' // key we want to remove
);
}
};
このヘルプを願っています!
私はこのソリューションを以下から組み合わせて見つけました: