Tim*_*ure 6 postgresql node.js sequelize.js
我正在尝试为我的应用程序设置 DELETE 路由,该路由将 Sequelize 与 Postgres 数据库结合使用。我有两个不同的模型,“产品”和“兴趣”(将兴趣视为一种类别或标签)。产品可以有多个兴趣,兴趣可以有多个产品,所以我使用了belongsToMany关联。其结果是,我有三个表:Products,Interests,和ProductInterests。这是我设置关联的方式:
对于产品:
Product.belongsToMany(models.Interest, {
foreignKey: 'productId',
through: models.ProductInterest,
as: 'interests',
onDelete: 'CASCADE',
hooks: true
});
Run Code Online (Sandbox Code Playgroud)
兴趣:
Interest.belongsToMany(models.Product, {
through: models.ProductInterest,
as: 'products',
foreignKey: 'interestId',
onDelete: 'CASCADE',
hooks: true
});
Run Code Online (Sandbox Code Playgroud)
这是在我的产品控制器中调用的方法:
destroy(req, res) {
return Product
.findById(req.params.productId, {
include: [
{
association: Product.associations.interests
}
]
})
.then((product) => {
if (!product) {
return res.status(404).send({
message: 'Product not found'
});
}
return product
.destroy()
// I've also tried the following:
// .destroy({
// truncate: true,
// cascade: true
// })
.then(() => res.status(204).send())
.catch(error => res.status(400).send(error));
})
.catch(error => res.status(400).send(error));
Run Code Online (Sandbox Code Playgroud)
这会导致无限循环,并记录以下查询:
Executing (default): SELECT "Product"."id", "Product"."title", "Product"."brand", "Product"."url", "Product"."imageUrl", "Product"."currentPrice", "Product"."male", "Product"."female", "Product"."asin", "Product"."storeName", "Product"."createdAt", "Product"."updatedAt", "ProductInterest"."createdAt" AS "ProductInterest.createdAt", "ProductInterest"."updatedAt" AS "ProductInterest.updatedAt", "ProductInterest"."interestId" AS "ProductInterest.interestId", "ProductInterest"."productId" AS "ProductInterest.productId" FROM "Products" AS "Product" INNER JOIN "ProductInterests" AS "ProductInterest" ON "Product"."id" = "ProductInterest"."productId" AND "ProductInterest"."interestId" = 1;
Executing (default): SELECT "Interest"."id", "Interest"."name", "Interest"."createdAt", "Interest"."updatedAt", "ProductInterest"."createdAt" AS "ProductInterest.createdAt", "ProductInterest"."updatedAt" AS "ProductInterest.updatedAt", "ProductInterest"."interestId" AS "ProductInterest.interestId", "ProductInterest"."productId" AS "ProductInterest.productId" FROM "Interests" AS "Interest" INNER JOIN "ProductInterests" AS "ProductInterest" ON "Interest"."id" = "ProductInterest"."interestId" AND "ProductInterest"."productId" = 6;
Run Code Online (Sandbox Code Playgroud)
我的意图是 a) 删除 Product 表中的产品;b) 删除 ProductInterest 表中的关联记录。如果产品被删除,我不希望删除兴趣本身。同样,如果兴趣被删除(只是关联),我不希望删除关联的产品。
我已经围绕这个尝试了几种不同的排列,但找不到正确的方法。任何帮助,将不胜感激。
更新
稍微调试 sequelize 代码让我觉得我不应该那样使用cascade。它基本上是尝试删除产品,然后(由于级联)尝试删除兴趣(我不想要),然后(由于级联)尝试删除相关产品等。仍然不确定是什么正确的解决办法是。
首先,belongsToMany 的默认行为是删除时的级联,它是用DOCS编写的
对于 1:1 和 1:m 关联,默认选项是 SET NULL(用于删除)和 CASCADE(用于更新)。对于 n:m,两者的默认值都是 CASCADE。这意味着,如果您从 n:m 关联的一侧删除或更新一行,则连接表中引用该行的所有行也将被删除或更新。
但我认为,除非您在表创建或迁移中创建外键引用时显式编写它,否则它不会起作用,如下所示:
queryInterface.createTable('ProductInterest', {
productId: {
type: Sequelize.INTEGER,
references: {
model: 'Product',
key: '_id',
},
onDelete: 'cascade'
},
interestId: {
type: Sequelize.INTEGER,
references: {
model: 'Interest',
key: '_id',
},
onDelete: 'cascade'
},
});
Run Code Online (Sandbox Code Playgroud)
根据我的理解,belongsToMany为给定的源和目标创建一个连接表模型 - 因此,对于您的两个表Product和Interest,Product.belongsToMany(Interest)创建一个新表ProductInterest,该表本质上只是一个 ProductId/InterestId 对的表。
Sequelize 的默认行为是,当删除 a 或 时Product,Interest它的条目ProductInterest也会被删除。简而言之,听起来您想要的删除约束默认就存在。我不确定将这些附加onDelete约束传递给关联会产生什么影响,但听起来您发现它们会导致一些意外的行为。
| 归档时间: |
|
| 查看次数: |
8876 次 |
| 最近记录: |