解决Sequelize 在belongsToMany 关联中的独特约束

asa*_*nas 5 database postgresql sequelize.js

我在我的项目中使用 Sequelize。这是两个模型:

const User = db.define('user', {
  name: Sequelize.STRING,
  password: Sequelize.STRING
})
const Product = db.define('product', {
  name: Sequelize.STRING,
  price: Sequelize.INTEGER
})
Run Code Online (Sandbox Code Playgroud)

现在用户可以购买产品,我有如下关联设置:

Product.belongsToMany(User, {through: 'UserProducts'})
User.belongsToMany(Product, {through: 'UserProducts'})
Run Code Online (Sandbox Code Playgroud)

我还有这个带有附加列的 UserProducts 表。

const UserProducts = db.define('UserProducts', {
  status: Sequelize.STRING
})
Run Code Online (Sandbox Code Playgroud)

Sequelize 使用 userId 和 productId 的组合创建一个复合键,并且只允许一个具有 userId 和 productId 组合的记录。例如,userId 2 和 productId 14。

这对我来说是个问题,因为有时人们想要多次购买。我需要以下场景之一才能工作:

  1. 不要使用复合键,而是在 UserProducts 中使用一个全新的自动增量列作为键。

  2. 不是单独使用 userId 和 productId 制作密钥,而是允许我在密钥中再添加一列,例如 ,status以便唯一密钥是三者的组合。

我确实想使用关联,因为它们提供了许多强大的方法,但想要更改唯一键以这样一种方式工作,即我可以添加具有相同用户 ID 和产品 ID 组合的多行。

由于我的模型/数据库已经在运行,我将需要利用迁移来进行此更改。

对此的任何帮助表示高度赞赏。

小智 14

如果其他人在Sequelize 的 v5 中遇到问题,仅在“通过”模型上指定主键是不够的。
您必须在直通模型上显式设置唯一属性。

User.belongsToMany(Product, { through: { model: UserProducts, unique: false } });
Product.belongsToMany(User, { through: { model: UserProducts, unique: false } });
Run Code Online (Sandbox Code Playgroud)

  • @AayushTaneja,以防万一你犯了和我一样的错误,它是 `{ through: { model: UserProducts, unique: false } }` 而不是 `{ through: UserProducts, unique: false }` (4认同)
  • unique: false 不起作用。即使存在多个重复的子项,它仍然显示单个子项。你有解决办法吗? (2认同)

小智 7

当主键不存在于直通模型时,Belongs-To-Many 创建一个唯一键。

由于您的UserProducts表中还有其他属性,您需要定义模型UserProducts,然后告诉续集使用该模型而不是创建自己的模型

class User extends Model {}
User.init({
    name: Sequelize.STRING,
    password: Sequelize.STRING
}, { sequelize })

class Product extends Model {}
ProjProductect.init({
    name: Sequelize.STRING,
    price: Sequelize.INTEGER
}, { sequelize })

class UserProducts extends Model {}
UserProducts.init({
  id: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  status: DataTypes.STRING
}, { sequelize })

User.belongsToMany(Project, { through: UserProducts })
Product.belongsToMany(User, { through: UserProducts })
Run Code Online (Sandbox Code Playgroud)

参考:Sequelize v4belongsToMany

更新

由于您使用的是 v3 并且已经为您的UserProducts表创建了一个模型,因此请使用以下代码段

UserProducts = db.define('UserProducts', {
  id: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  status: DataTypes.STRING
})
Run Code Online (Sandbox Code Playgroud)