【问题标题】:Sequelize, foreign keys as composite primary keySequelize,外键作为复合主键
【发布时间】:2016-08-21 08:58:57
【问题描述】:

可以定义两个外键作为模型的复合主键吗?

一个用户只能是一个家庭的成员,一个家庭可以有多个成员,family-members表需要用户和家庭的引用

const User = sequelize.define(
    'User',
    {
        id: { type: dataTypes.INTEGER.UNSIGNED, autoIncrement: true, primaryKey: true },
        name: { type: dataTypes.STRING(30) },
        email: { type: dataTypes.STRING(30) }
        ...
    },
    {
        classMethods: {
            associate(models) {
                User.hasOne(models.FamilyMember, {
                    foreignKey: 'user_id'
                }
            }
        }
    }
)

const Family = sequelize.define(
    'Family',
    {
        name: { type: dataTypes.STRING(30) }
    },
    {
        classMethods: {
            associate(models) {
                Family.hasMany(models.FamilyMember, {
                    foreignKey: 'family_id'
                }
            }
        }
    }
)

const FamilyMember = sequelize.define(
    'FamilyMember',
    {
        name: { type: dataTypes.STRING(30) },
        /*
        family_id and user_id will be here after associations but I wanted them to be a composite primaryKey
        */
    }
)

【问题讨论】:

  • 我不确定您是否可以制作复合主键,但我知道您可以制作复合唯一键。不过,我不确定它们是否对您的情况有所帮助。

标签: node.js sequelize.js


【解决方案1】:

事实上,我几乎从文档中得到了解决方案:

User = sequelize.define('user', {});
Project = sequelize.define('project', {});
UserProjects = sequelize.define('userProjects', {
    status: DataTypes.STRING
});

User.belongsToMany(Project, { through: UserProjects });
Project.belongsToMany(User, { through: UserProjects });

默认情况下,上面的代码会将 projectId 和 userId 添加到 UserProjects 表中,并删除任何先前定义的主键属性 - 该表将由两个表的键组合唯一标识,没有理由有其他的PK列。

Source

【讨论】:

  • 但是如何在使用 sequelize-cli 的迁移中做到这一点?
  • 在迁移中,您可以在定义表结构后添加此对象,例如:` uniqueKeys: [{ name: "UniqueUserPermissions", singleField: false, fields: ["PermissionId", "UserId" ], }]`
【解决方案2】:

对于希望在执行迁移时基于联接表中的列(键)创建复合索引主键的任何人。您需要为希望充当表的组合主键的两列添加主键约束。

module.exports = {
  up: function (queryInterface, Sequelize) {
    return queryInterface.createTable('itemtags', {
      itemId: {
        type: Sequelize.INTEGER,
        references: {
          model: 'items',
          key: 'id',
        },
        onDelete: 'CASCADE',
        onUpdate: 'CASCADE',
        allowNull: false
      },
      tagId: {
        type: Sequelize.INTEGER,
        references: {
          model: 'tags',
          key: 'id',
        },
        onDelete: 'CASCADE',
        onUpdate: 'CASCADE',
        allowNull: false
      }
    })
      .then(() => {
        return queryInterface.addConstraint('itemtags', ['itemId', 'tagId'], {
          type: 'primary key',
          name: 'gametag_pkey'
        });
      });
  },
  down: function (queryInterface, Sequelize) {
    return queryInterface.dropTable('gametags');
  }
};

这与在 postgres 中执行 ALTER TABLE ONLY my_table ADD CONSTRAINT pk_my_table PRIMARY KEY(column1,column2); 大致相同。

【讨论】:

  • 当我尝试此操作时出现错误,“不允许表“患者”的多个主键”。你遇到过这个问题吗?
  • @MaykonMorais 听起来您正试图在已经有一个主键约束的表上添加一个约束。
  • 你是对的。首先,我放弃对主键的约束并添加我的复合主键。
猜你喜欢
  • 2021-02-01
  • 1970-01-01
  • 2021-07-24
  • 1970-01-01
  • 2015-05-14
  • 2012-05-20
  • 2012-01-27
  • 2020-03-28
  • 2018-04-07
相关资源
最近更新 更多