指南 参考 源代码
public class | source

Association

在 Sequelize 中创建关联是通过在模型(源)上调用 belongsTo / hasOne / hasMany / belongsToMany 函数之一,并提供另一个模型作为函数的第一个参数(目标)来完成的。

  • hasOne - 在目标模型中添加外键,并在源模型中添加单数关联mixin。
  • belongsTo - 在源模型中添加外键和单数关联mixin。
  • hasMany - 在目标模型中添加外键,并在源模型中添加复数关联mixin。
  • belongsToMany - 创建一个N:M关联,使用连接表,并在源模型中添加复数关联mixin。连接表使用sourceId和targetId创建。

创建关联会在属性中添加外键约束。所有关联在更新时使用CASCADE,在删除时使用SET NULL,除了n:m关联,它在删除时也使用CASCADE

创建关联时,可以通过as选项提供别名。当同一个模型关联两次,或者希望关联的名称与目标模型的名称不同时,这很有用。

例如,考虑用户拥有多个图片,其中一个图片是用户个人资料图片的情况。所有图片都有一个userId,但是用户模型还有一个profilePictureId,以便能够轻松加载用户的个人资料图片。

User.hasMany(Picture)
User.belongsTo(Picture, { as: 'ProfilePicture', constraints: false })

user.getPictures() // gets you all pictures
user.getProfilePicture() // gets you only the profile picture

User.findAll({
  where: ...,
  include: [
    { model: Picture }, // load all pictures
    { model: Picture, as: 'ProfilePicture' }, // load the profile picture.
    // Notice that the spelling must be the exact same as the one in the association
  ]
})

要完全控制Sequelize添加的外键列,可以使用foreignKey选项。它可以是一个字符串,指定列名,也可以是一个对象类型定义,等同于传递给sequelize.define的那些。

User.hasMany(Picture, { foreignKey: 'uid' })

现在,Picture中的外键列将被称为uid,而不是默认的userId

User.hasMany(Picture, {
  foreignKey: {
    name: 'uid',
    allowNull: false
  }
})

这指定了uid列不能为null。在大多数情况下,这已经由Sequelize自动创建的外键约束覆盖,但在外键被禁用时(例如,由于循环引用(参见下面的constraints: false))可能会很有用。

获取关联模型时,可以将查询限制为仅加载一些模型。这些查询的写法与find/findAll的查询相同。要仅获取JPG格式的图片,可以执行以下操作

user.getPictures({
  where: {
    format: 'jpg'
  }
})

更新和添加新的关联有几种方法。继续我们关于用户和图片的例子

user.addPicture(p) // Add a single picture
user.setPictures([p1, p2]) // Associate user with ONLY these two picture, all other associations will be deleted
user.addPictures([p1, p2]) // Associate user with these two pictures, but don't touch any current associations

如果关联模型只有一个主键,则不必将完整对象传递给关联函数。

user.addPicture(req.query.pid) // Here pid is just an integer, representing the primary key of the picture

在上面的例子中,我们指定了一个用户属于他的个人资料图片。从概念上讲,这可能没有意义,但由于我们希望将外键添加到用户模型中,所以这是实现的方法。

注意我们也为个人资料图片指定了constraints: false。这是因为我们从用户到图片(profilePictureId)添加了一个外键,并且从图片到用户(userId)添加了一个外键。如果我们同时为两者添加外键,则会创建一个循环依赖关系,Sequelize将不知道先创建哪个表,因为用户依赖于图片,而图片依赖于用户。这些问题会在模型同步到数据库之前由Sequelize检测到,您将收到类似于Error: Cyclic dependency found. 'users' is dependent of itself的错误。如果您遇到这种情况,则应禁用一些约束,或完全重新思考您的关联关系。

成员摘要

公共成员
public

关联的类型。

public
public

公共成员

public associationType: string source

关联的类型。HasManyBelongsToHasOneBelongsToMany之一。

public source: Model source

public target: Model source