I have a model defined as follows:
sequelize.define('game', {
id: {
type: type.INTEGER,
primaryKey: true,
autoIncrement: true,
},
leaderId: {
type: type.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'id',
},
},
playerId: {
type: type.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'id',
},
},
status: {
type: type.STRING,
defaultValue: 'running',
},
notes: {
type: type.TEXT,
},
});
I'm trying to use Sequelize to load all game object and include the User with the id equal to the playerId field.
The problem is I have two attributes (leaderId, playerId) which reference the User model so using include as follows does not work:
Game.findAll({
where: conditions,
include: [{ model: User }],
})
Is there a way to specify which attribute the include command should use?
const game = sequelize.define('game', {
id: {
type: type.INTEGER,
primaryKey: true,
autoIncrement: true,
},
leaderId: {
type: type.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'id',
},
},
playerId: {
type: type.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'id',
},
as:'player'
},
status: {
type: type.STRING,
defaultValue: 'running',
},
notes: {
type: type.TEXT,
},
});
game.associate = function (models) {
game.belongsTo(models.user, {
foreignKey: "playerId",
as: "player",
});
game.belongsTo(models.user, {
foreignKey: "leaderId",
as: "leader",
});
};
Game.findAll({
where: conditions,
include: ['player'],
})
Or
Game.findAll({
where: conditions,
include: [{model: User, as: 'player' }],
})
Or
Game.findAll({
where: conditions,
include: [{model: User, as: 'player', foreignKey: 'playerId' }],
})
https://github.com/nkhs/node-sequelize
Related
I dont know why I am getting this error error: SequelizeDatabaseError: Unknown column 'student-> section ->grademapping.studentId' in 'field list' I just follow this documentation on how to use belongsToMany did i miss something on the documentation? https://sebhastian.com/sequelize-belongstomany/
let student = await Database.getConnection().models.Student;
let grademapping = await Database.getConnection().models.Grademapping;
let section = await Database.getConnection().models.Section;
let taxtypemapping = await student.findAll({
attributes:['_id','FirstName','LastName', 'section.Description'],
include:[
{ model: section, attribute:[] }
],
raw: true
})
the models
class taxtypedetails extends Sequelize.Model {}
Section.init(
{
_id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
Description: {
type: Sequelize.STRING,
},
},
{ sequelize, tableName: 'section', timestamps: false },
)
class Student extends Sequelize.Model {}
Student.init(
{
_id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
FirstName: {
type: Sequelize.STRING,
},
LastName: {
type: Sequelize.STRING,
},
},
{ sequelize, tableName: 'student', timestamps: false },
)
class Grademapping extends Sequelize.Model {}
Grademapping.init(
{
_id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
sectionID: {
type: Sequelize.INTEGER,
references: {
model: 'section',
key: '_id',
},
},
studentID: {
type: Sequelize.INTEGER,
references: {
model: 'student',
key: '_id',
},
}
},
{ sequelize, tableName: 'grademapping', timestamps: false },
)
student.belongsToMany(section,{through: grademapping})
section.belongsToMany(student,{through: grademapping})
I'm trying to make a filter songs, i have an array of genres ids that i retrieve from the client, i do this for get all the audios from one id:
Audio.findAll({
include: [{
model: db.Genres,
as: "genres",
where: {
id: {
[Op.and]: [1]
}
},
}]
})
But i need to get all audios that contains all the ids from array of genres/moods, also want filter audios by genres ids and moods ids, but i don't know how to make it, any idea? (One song can have many genres/moods)
Song Model
const Audio = sequelize.define('Audio', {
id: {
autoIncrement: true,
type: DataTypes.INTEGER(30),
allowNull: false,
primaryKey: true
},
name: {
type: DataTypes.STRING(255),
allowNull: false
},
})
Audio.associate = function(models) {
Audio.belongsToMany(models.Genres, {through: 'AudioGenres', foreignKey: 'id_audio', as: 'genres'})
Audio.belongsToMany(models.Moods, {through: 'AudioMoods', foreignKey: 'id_audio', as: 'moods'})
}
AudioGenreModel
const AudioGenres = sequelize.define('AudioGenres', {
id_audio: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
references: {
model: 'Audio',
key: 'id'
}
},
id_genre: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
references: {
model: 'Genres',
key: 'id'
}
})
AudioGenres.associate = function(models) {
AudioGenres.belongsTo(models.Audio, {foreignKey: 'id_audio'})
AudioGenres.belongsTo(models.Genres, {foreignKey: 'id_genre'})
};
AudioMoodModel
const AudioMoods = sequelize.define('AudioMoods', {
id_audio: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
references: {
model: 'Audio',
key: 'id'
}
},
id_mood: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
references: {
model: 'Mods',
key: 'id'
}
})
AudioMoods.associate = function(models) {
AudioMoods.belongsTo(models.Audio, {foreignKey: 'id_audio'})
AudioMoods.belongsTo(models.Mods, {foreignKey: 'id_mood'})
};
Moods and Genres Model
const Moods = sequelize.define('Moods', {
name: {
type: DataTypes.STRING(255),
allowNull: false
},
})
Moods.associate = function(models) {
Moods.belongsToMany(models.Audio, {through: 'AudioMoods', foreignKey: 'id_mood', as: 'audios'})
}
const Genres = sequelize.define('Genres', {
name: {
type: DataTypes.STRING(255),
allowNull: false
},
})
Genres.associate = function(models) {
Genres.belongsToMany(models.Audio, {through: 'AudioGenres', foreignKey: 'id_genre', as: 'audios'})
}
I suppose you should add all conditions in AND operator in both include options like this:
Audio.findAll({
include: [{
model: db.Genres,
as: "genres",
where: {
[Op.and]: [{ id: 1}, { id: 3},{ id: 2}]
},
}, {
model: db.Moods,
as: "moods",
where: {
[Op.and]: [{ id: 4}, { id: 5},{ id: 6}]
},
}]
})
For context, I am new to sequelize, and I have googled extensively to find this before reaching out to the community. I would be grateful for any help :)
I have 3 models to build a "family unit" that basically look like code below (dialect is mysql fyi). What I desire is to make a call through the user table to get a data model that looks like this:
User => { Object of User }
=> id
=> firstName
=> lastName
=> email
=> active
=> families => [ Array of Family ]
=> id
=> name
=> crew => [ Array of Users ]
=> id
=> firstName
=> lastName
=> email
=> active
This is the code I'm using to try and accomplish this and getting close but no users on the through table coming back.
User.findOne({
where: { id: 'my-guid-info'},
include: {
all: true,
nested: true,
through: {
model: "Member",
},
},
});
And here is the model code:
Family.init(
{
id: {
primaryKey: true,
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
validate: {
notNull: true,
},
},
name: { type: DataTypes.STRING, required: true },
},
{
sequelize,
modelName: "Family",
timestamps: true,
paranoid: true,
});
User.init(
{
id: {
primaryKey: true,
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
validate: {
notNull: true,
},
},
active: { type: DataTypes.BOOLEAN, defaultValue: true },
firstName: DataTypes.STRING,
lastName: DataTypes.STRING,
email: {
type: DataTypes.STRING,
unique: true,
required: true,
allowNull: false,
validate: {
isEmail: true,
notNull: true,
},
},
},
{
timestamps: true,
paranoid: true,
defaultScope: {
attributes: { exclude: ["hash", "salt"] },
},
});
Member.init(
{
id: {
primaryKey: true,
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
validate: {
notNull: true,
},
},
userId: {
type: DataTypes.UUID,
references: { model: "User", key: "id" },
},
familyId: {
type: DataTypes.UUID,
references: { model: "Family", key: "id" },
},
relationship: {
type: DataTypes.ENUM("child", "parent", "primary"),
},
},
{
sequelize,
modelName: "Member",
timestamps: true,
});
I also have these associations setup on each model respectively.
User.associate = (models) => {
User.belongsToMany(models.Family, {
as: "families",
through: {
model: models.Member,
},
foreignKey: "userId",
otherKey: "familyId",
});
};
Family.associate = (models) => {
Family.belongsToMany(models.User, {
as: "crew",
otherKey: "userId",
attributes: {
exclude: ["hash", "salt"],
},
through: { model: models.Member },
});
};
Member.associate = (models) => {
Member.belongsTo(models.User, { foreignKey: "userId" });
Member.belongsTo(models.Family, { foreignKey: "familyId" });
};
Any direction, would be really appreciated, as I feel like I have tried all the elements of the relevant documentation, and several stackoverflow threads.
I’m new with sequelize I’m trying to make a request with associate tables
I have a first model called Experience
module.exports = function (sequelize, DataTypes) {
const Experience = sequelize.define('experience', {
internalId: {
type: DataTypes.BIGINT,
unique: true,
allowNull: false,
},
label: {
type: DataTypes.STRING,
unique: false,
allowNull: false,
},
picture: {
type: DataTypes.TEXT,
unique: false,
allowNull: true,
},
type: {
type: DataTypes.STRING,
validate: {
isIn: {
args: [[
'generic',
'specific',
]],
msg: 'Must be a valid type',
},
},
unique: false,
allowNull: true,
},
author: {
type: DataTypes.STRING,
unique: false,
allowNull: true,
defaultValue: 'import',
},
isActive: {
type: DataTypes.BOOLEAN,
defaultValue: true,
},
});
Experience.associate = (models) => {
Experience.belongsToMany(models.Tag, {
as: 'Tags',
through: models.ExperienceTag,
});
};
return Experience;
};
a second called Tags
module.exports = function (sequelize, DataTypes) {
const Tag = sequelize.define('tag', {
internalId: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
name: {
type: DataTypes.STRING,
unique: false,
allowNull: false,
},
author: {
type: DataTypes.STRING,
unique: false,
allowNull: true,
defaultValue: 'import',
},
isActive: {
type: DataTypes.BOOLEAN,
defaultValue: true,
},
});
Tag.associate = (models) => {
Tag.belongsToMany(models.Experience, {
as: 'Experiences',
through: models.ExperienceTag,
});
};
return Tag;
};
The association table name was ExperienceTags
I would like get all the Experiencewho have a tagId = 44
This is my request:
Experience.findAll({
include: [{
model: ExperienceTag,
where: { tagId: 44 },
}],
})
.then((results) => {
winston.warn(JSON.stringify(results, null, 2));
res.status(200)
.send(results);
})
.catch(error => res.status(500)
.send({ error: error.toString() }));
But when I execute it I have an error like:
{
"error": "SequelizeEagerLoadingError: experienceTag is not associated to experience!"
}
I think you like to include Tag rather than ExperienceTag, the following example may help you
Experience.findAll({
include: [{
model: Tag, //model name which you want to include
as: 'Tags', // you have to pass alias as you used while defining
where: { tagId: 44 },
}],
})
I think , you need to add as: 'Experiences' , in your include as you have defined association with alias
Change this
Experience.findAll({
include: [{
model: ExperienceTag,
where: { tagId: 44 },
}],
})
With
Experience.findAll({
include: [{
model: ExperienceTag,
as: 'Experiences', // <---- HERE
where: { tagId: 44 },
}],
})
I am working on a NodeJs application using sequelize as an ORM with exciting database , so I had to use sequelize model generator in order to generate the models for my application.
Here's an example of the generation output:
Category.js
module.exports = function(sequelize, DataTypes) {
return sequelize.define('category', {
id: {
type: DataTypes.STRING(128),
allowNull: false,
primaryKey: true,
field: 'id'
},
name: {
type: DataTypes.TEXT,
allowNull: true,
field: 'name'
}
}, {
tableName: 'category'
});
};
Product.js
module.exports = function(sequelize, DataTypes) {
return sequelize.define('product', {
id: {
type: DataTypes.STRING(128),
allowNull: false,
primaryKey: true,
field: 'id'
},
category: {
type: DataTypes.STRING(128),
allowNull: false,
references: {
model: 'category',
key: 'id'
},
field: 'category'
},
name: {
type: DataTypes.TEXT,
allowNull: true,
field: 'name'
}
}, {
tableName: 'product'
});
};
and then inside my controller I have this query :
models.product.findOne({
where: {
id: req.body.id
}
}).then(function (obj) {
//return the product data
console.log(product.category) //works
console.log(product.category.name) //return undefined
});
The question is how can I access to the parent table attribute via the same query findOne ? Is there something like or equivalent to product.category.id ?
if you have associated both the models... then try this
module.exports = function(sequelize, DataTypes) {
return sequelize.define('product', {
id: {
type: DataTypes.STRING(128),
allowNull: false,
primaryKey: true,
field: 'id'
},
category_id: {
type: DataTypes.STRING(128),
allowNull: false,
references: {
model: 'category',
key: 'id'
},
field: 'category'
},
name: {
type: DataTypes.TEXT,
allowNull: true,
field: 'name'
}
}, {
tableName: 'product'
});
}
models.product.findOne({
where: {
id: req.body.id
},
include: [{
model: category,
required: false
}]
}).then(function (obj) {
//return the product data
console.log(product.category) //works
console.log(product.category.name) //return undefined
});
Associate like this
product.hasMany(db.category, {
foreignKey: 'category_id',
onDelete: 'cascade'
});
category.belongsTo(db.product, {
foreignKey: 'category_id',
targetKey: 'id',
constraints: true
});