【问题标题】:Sequelize throwing error "must be unique"Sequelize 抛出错误“必须是唯一的”
【发布时间】:2021-02-13 02:27:16
【问题描述】:

我将 Sequelize 与我的 mysql 数据库一起使用,并且与作为直通表的 CostumerDriverTransaction 模型具有多对多关系

当我尝试从这个表中创建一个行时,我收到了这个错误"message": "driverId must be unique"

CostumerDriverTransaction 模型

const CostumerDriverTransaction = sequelize.define('CostumerDriverTransaction', {
costumerId: {
  type:DataTypes.INTEGER,
},
driverId: {
  type:DataTypes.INTEGER,
},
restaurantId: {
  type:DataTypes.INTEGER,
},
orderId: DataTypes.INTEGER,
transactionId: {
  type:DataTypes.INTEGER,
  primaryKey:true,
},
},{});

这个协会:

index.js

db.user.belongsToMany(db.driver,{
  through:db.costumerDriverTransaction,
  foreignKey:{
    name:'costumerId'
  }
});
db.driver.belongsToMany(db.user,{
  through:db.costumerDriverTransaction,
  foreignKey:{
    name:'driverId'
  }
});
db.user.hasMany(db.costumerDriverTransaction,{
  foreignKey:{
    name:'costumerId'
  }
});
db.driver.hasMany(db.costumerDriverTransaction,{
  foreignKey:{
    name:'driverId'
  }
});
db.costumerDriverTransaction.belongsTo(db.user,{
  foreignKey:{
    name:'costumerId'
  }
});
db.costumerDriverTransaction.belongsTo(db.driver,{
  foreignKey:{
    name:'driverId'
  }
});

请问有什么问题?

【问题讨论】:

  • 您不需要包含关系列,它们会自动创建。您也不需要从CostumerDriverTransaction 定义关系,除非您打算直接查询它而不是“通过”它。

标签: mysql node.js express sequelize.js


【解决方案1】:

如报错所示,需要将driverId设置为唯一,即:

const CostumerDriverTransaction = sequelize.define('CostumerDriverTransaction', {
costumerId: {
  type:DataTypes.INTEGER,
},
driverId: {
  type:DataTypes.INTEGER,
  unique: true
},
restaurantId: {
  type:DataTypes.INTEGER,
},
orderId: DataTypes.INTEGER,
transactionId: {
  type:DataTypes.INTEGER,
  primaryKey:true,
},
},{});

【讨论】:

  • 我不认为这是正确的,他更有可能插入重复数据并且唯一性是由关系设置的。问题是模型定义不正确。
  • @doublesharp 是的,你是对的,这就是问题所在,但哪里错了?
【解决方案2】:

大多数列不需要在您的定义中指定,而是会自动创建,例如在主键和关系字段中。如果您想覆盖它们,您可以在列定义中指定它们(这很值得注意,因为您的示例中的 transactionId 在自动生成时会变为 id

在这里,我们为您的每个对象创建模型,然后定义它们之间的所有不同关系。因为关系表是“超级”多对多,因为它拥有自己的主键而不是复合表,您可以从它或“通过”它的任何其他模型中查询。

如果您不希望表格中的createdAtupdatedAt 列将timestamps: false, 传递到sequelize.define() 的选项中。

// your other models
const User = sequelize.define('User', {}, {});
const Driver = sequelize.define('Driver', {}, {});
const Restaurant = sequelize.define('Restaurant', {}, {});
const Order = sequelize.define('Order', {}, {});

// the relational table, note that leaving off the primary key will use `id` instead of transactionId
const CostumerDriverTransaction = sequelize.define('CostumerDriverTransaction', {}, {});

// relate the transaction to the other 
CostumerDriverTransaction.belongsTo(User, { foreignKey: 'customerId' });
CostumerDriverTransaction.belongsTo(Driver, { foreignKey: 'driverId' });
CostumerDriverTransaction.belongsTo(Restaurant, { foreignKey: 'restaurantId' });
CostumerDriverTransaction.belongsTo(Order, { foreignKey: 'orderId' });

// relate the models to the transactions
User.hasMany(CostumerDriverTransaction, { as: 'transactions', foreignKey: 'customerId' });
// relate models to other models through transactions
User.hasMany(Driver, { as: 'drivers', through: 'CostumerDriverTransaction', foreignKey: 'customerId', otherKey: 'driverId' });
User.hasMany(Restaurant, { as: 'restaurants', through: 'CostumerDriverTransaction', foreignKey: 'customerId', otherKey: 'restaurantId' });
User.hasMany(Order, { as: 'orders', through: 'CostumerDriverTransaction', foreignKey: 'customerId', otherKey: 'orderId' });

// Drivers
Driver.hasMany(CostumerDriverTransaction, { foreignKey: 'driverId' });
Driver.hasMany(User, { as: 'customers', through: 'CostumerDriverTransaction', foreignKey: 'driverId', otherKey: 'customerId' });
Driver.hasMany(Restaurant, { as: 'restaurants', through: 'CostumerDriverTransaction', foreignKey: 'driverId', otherKey: 'restaurantId' });
Driver.hasMany(Order, { as: 'orders', through: 'CostumerDriverTransaction', foreignKey: 'driverId', otherKey: 'orderId' });

// Restaurants
Restaurant.hasMany(CostumerDriverTransaction, { foreignKey: 'restaurantId' });
Restaurant.hasMany(Driver, { as: 'drivers', through: 'CostumerDriverTransaction', foreignKey: 'restaurantId', otherKey: 'driverId' });
Restaurant.hasMany(User, { as: 'customers', through: 'CostumerDriverTransaction', foreignKey: 'restaurantId', otherKey: 'customerId' });
Restaurant.hasMany(Order, { as: 'orders', through: 'CostumerDriverTransaction', foreignKey: 'restaurantId', otherKey: 'orderId' });

// Orders
Order.hasMany(CostumerDriverTransaction, { foreignKey: 'orderId' });
Order.hasMany(Driver, { as: 'drivers', through: 'CostumerDriverTransaction', foreignKey: 'orderId', otherKey: 'driverId' });
Order.hasMany(User, { as: 'customers', through: 'CostumerDriverTransaction', foreignKey: 'orderId', otherKey: 'customerId' });
Order.hasMany(Restaurant, { as: 'restaurants', through: 'CostumerDriverTransaction', foreignKey: 'orderId', otherKey: 'restaurantId' });

这将创建具有以下主键和关系列的模型:

// User
{
  id: primary key,
  createdAt: create date,
  updatedAt: update date,
}

// Driver
{
  id: primary key,
  createdAt: create date,
  updatedAt: update date,
}

// Restaurant
{
  id: primary key,
  createdAt: create date,
  updatedAt: update date,
}

// Order
{
  id: primary key,
  createdAt: create date,
  updatedAt: update date,
}

// Transaction
{
  id: primary key,
  userId: relationship to User,
  driverId: relationship to Driver,
  restaurantId: relationship to Restaurant,
  orderId: relationship to Order,
  createdAt: create date,
  updatedAt: update date,
}

【讨论】:

    猜你喜欢
    • 2016-05-03
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 2021-07-18
    • 2017-11-22
    • 1970-01-01
    相关资源
    最近更新 更多