在 Sequelize 中从关联创建复合主键

Posted

技术标签:

【中文标题】在 Sequelize 中从关联创建复合主键【英文标题】:Create Composite Primary Key From Association in Sequelize 【发布时间】:2019-03-05 20:30:33 【问题描述】:

我有两个模型:PersonTeam

假设模型很简单(假设基本的字符串/整数类型):

team:
  id
  name
  ownerId

person:
  id
  name

我想表示这两个模型之间的关联,这样一个人可以属于多个团队,一个团队可以属于多个人(即多对多关系)。

在 Sequelize 中这样做很简单:

Team.belongsToMany(Person, through: 'TeamPerson')
Person.belongsToMany(Team, through: 'TeamPerson')

这将创建一个名为TeamPerson 的新表,其中包含teamIdpersonId。我假设这个表的主键是两个 ID 的组合。

我也希望每支球队都有一名队长:

Team.belongsTo(Person as: 'captain')

这会将captainId 添加到团队模型中。

这是我的问题,我希望一个人能够创建一个团队,但我不希望他们能够创建两个同名的团队。但是,我确实希望允许其他人创建一个与其他人同名的团队。因此,用户 ID 1 不能有两个名为“Falcons”的团队,但用户 ID 1 可以有一个名为“Falcons”的团队,而用户 ID 2 可以有一个名为“Falcons”的团队。

基本上 name 和 CaptainId 应该是 Team 表上的复合主键。谁能告诉我如何实现这一目标?

【问题讨论】:

【参考方案1】:

您可以在允许创建新项目之前查询以前存在的人员/项目...大致:

    Person.findAll(
        attributes: ['id'],
        include: [
            model: Team,
            where :  name : ***TEAM_NAME_PARAM*** 
            attributes: [
                [Sequelize.fn('count', 'id'), 'number_of_teams']
           ]
        ],
        where:  id : ***USER_ID_PARAM***,
        group: ['id']
        )        
        .then(myTeams => 
            if (myTeams.length == 0 || myTeams.Team.number_of_teams == 0) 
               // proceed with creating new team
             else 
               // give some error message (you already have a team with that name)
            
            ...

【讨论】:

感谢您的回复,但我必须记住,对于任何涉及创建/更新的查询,我都必须这样做。另外,这不是更多的开销吗?一定有办法在模型定义中定义 我是打算说这是不可能的......但文档另有说明。签出 QueryInterface 对象。我没有这方面的经验,因为我更喜欢在原始 SQL 中创建我的数据库对象。 create unique index my_new_index on team_table (team_name, team_captain_id) 在任何一种情况下,您都需要一些代码来告知用户他们的新团队被拒绝的原因。

以上是关于在 Sequelize 中从关联创建复合主键的主要内容,如果未能解决你的问题,请参考以下文章

具有复合主键和特定 VARCHAR 长度的 NodeJS MySQL ORM

sql工作台中的复合主键与自动递增主键

如何在 SQL 中定义复合主键?

使用关联数据创建复合索引?

使用关联数据创建复合索引?

使用 Cloudformation 创建具有复合主键的 DynamoDB