web-dev-qa-db-fra.com

sequelize - Impossible d'ajouter une contrainte de clé étrangère

J'essaie d'établir une relation 1: 1 entre deux tables. La table RefreshToken aura deux clés étrangères reliées à la table Utilisateurs, comme dans cette image: enter image description here

J'ai utilisé sequelize-auto pour générer mes modèles séquentiels.

Modèle utilisateur:

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('Users', {
    idUsers: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true
    },
    name: {
      type: DataTypes.STRING(45),
      allowNull: true
    },
    mail: {
      type: DataTypes.STRING(45),
      allowNull: false,
      primaryKey: true
    }
  }, {
    tableName: 'Users'
  });
};

Modèle RefreshToken:

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('RefreshToken', {
    idRefreshToken: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true
    },
    token: {
      type: DataTypes.TEXT,
      allowNull: true
    },
    userId: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true,
      references: {
        model: 'Users',
        key: 'idUsers'
      }
    },
    userEmail: {
      type: DataTypes.STRING(45),
      allowNull: false,
      primaryKey: true,
      references: {
        model: 'Users',
        key: 'mail'
      }
    }
  }, {
    tableName: 'RefreshToken'
  });
};

Lorsque j'exécute l'application, je reçois cette erreur:

Erreur de rejet non gérée: SequelizeDatabaseError: ER_CANNOT_ADD_FOREIGN: impossible d'ajouter une contrainte de clé étrangère

J'ai essayé d'ajouter explicitement la relation, en ajoutant dans le tableau des utilisateurs:

User.associate = (models) => {
    User.hasOne(models.RefreshToken, {
      foreignKey: 'userId'
    });
    User.hasOne(models.RefreshToken, {
      foreignKey: 'userEmail'
    });
  };

et dans RefreshToken:

RefreshToken.associate = (models) => {
    RefreshToken.belongsTo(models.Users, {
      foreignKey: 'userId'
    });
    RefreshToken.belongsTo(models.Users, {
      foreignKey: 'userEmail'
    });
  };

Mais je reçois à nouveau la même erreur. Si je supprime les références dans la table RefreshToken, je ne vois aucune erreur, mais lorsque je vérifie la base de données, je ne vois aucune contrainte de relation de clé étrangère avec l'adresse e-mail et l'ID de l'utilisateur

10
tinytanks

Cette erreur de type courante se produit principalement en raison de

1. Lorsque le type de données de clé primaire et la clé étrangère type de données ne correspondaient pas

return sequelize.define('RefreshToken', {
    userId: {
      type: DataTypes.INTEGER(11), // The data type defined here and 
      references: {
        model: 'Users',
        key: 'idUsers'
      }
    }, 


return sequelize.define('Users', {
    idUsers: {
      type: DataTypes.INTEGER(11),  // This data type should be the same
    },

2. Lorsque la clé référencée n'est pas une clé primaire ou unique.

Vous ne pouvez pas avoir deux clés primaires, les autres clés référencées doivent donc être définies comme uniques. unique:true

 return sequelize.define('Users', {
    idUsers: {
      primaryKey: true  
    },
    mail: {
      type: DataTypes.STRING(45),
      allowNull: false,
      primaryKey: true   // You should change this to 'unique:true'. you cant hv two primary keys in one table. 
    }
14
bereket gebredingle

Je vois deux problèmes:

Aucune table ne doit contenir deux clés primaires et userId ne doit pas être en entier, il doit être un UUID.

J'avais une clé étrangère définie sur INT et cela m'a donné une erreur:

Rejet non géré SequelizeDatabaseError: la contrainte de clé étrangère "nom_contrainte_ici" ne peut pas être implémentée

Essayez de changer:

userId: {
  type: DataTypes.INTEGER(11),
  allowNull: false,
  primaryKey: true,
  references: {
    model: 'Users',
    key: 'idUsers'
  }
},

À

userId: {
  type: DataTypes.UUID,
  allowNull: false,
  foreignKey: true,
  references: {
    model: 'Users',
    key: 'idUsers'
  }
},
0
QuickStyles