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:
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
Cette erreur de type courante se produit principalement en raison de
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
},
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.
}
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'
}
},