web-dev-qa-db-fra.com

Sequelize, clés étrangères en tant que clé primaire composite

est-il possible de définir deux clés étrangères comme clé primaire composite d'un modèle?

Un utilisateur ne peut être membre que d'une seule famille, une famille peut avoir plusieurs membres et la table des membres de la famille a besoin des références de l'utilisateur et de la famille

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
        */
    }
)
14
Sergio Flores

En fait, j'ai presque obtenu la solution de la documentation:

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 });

Par défaut, le code ci-dessus ajoutera projectId et userId à la table UserProjects et supprimera tout attribut de clé primaire précédemment défini - la table sera identifiée de manière unique par la combinaison des clés des deux tables, et il n'y a aucune raison d'avoir d'autres PK Colonnes.

Source

12
Sergio Flores

Pour toute personne souhaitant créer une clé primaire d'index composite basée sur les colonnes (clés) de votre table de jointure lors des migrations. Vous devrez ajouter une contrainte de clé primaire pour les deux colonnes que vous souhaitez utiliser comme clé primaire combinée pour la table.

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');
  }
};

Ce qui équivaut à peu près à faire ALTER TABLE ONLY my_table ADD CONSTRAINT pk_my_table PRIMARY KEY(column1,column2); en postgres.

4
holmberd