I have a list of many to many of the people tables and lists. I need to make a query that includes the relation table, something like:
SELECT p.id, pl.id
FROM people p inner join peopletolists pl
WHERE p.id == pl.id
My models:
Lists model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const lists = sequelize.define('lists', {
listId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
nome: DataTypes.STRING(50),
status: DataTypes.STRING(1),
parametros: DataTypes.STRING(500)
}, {
timestamps: false,
});
lists.associate = function(models) {
lists.belongsToMany(models.people, {
through: models.peopletolists,
foreignKey: 'listId',
});
}
return lists;
};
People model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const people = sequelize.define('people', {
peopleId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
cpf: DataTypes.STRING(11),
name: DataTypes.STRING(50),
city: DataTypes.STRING(50),
}, {
timestamps: false
});
people.associate = function (models) {
people.belongsToMany(models.lists, {
through: models.peopletolists,
foreignKey: 'peopleId'
});
}
return people;
};
N:M model:
'use strict';
module.exports = function (sequelize, DataTypes) {
const peopletolists = sequelize.define("peopletolists", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true,
},
listId: {
type: DataTypes.INTEGER,
references: {
model: 'lists',
key: 'listId'
},
allowNull: false
},
peopleId: {
type: DataTypes.INTEGER,
references: {
model: 'people',
key: 'peopleId'
},
allowNull: false
}
}, {
timestamps: false
});
return peopletolists;
}
Query:
router.get('/', function (req, res, next) {
model.lists.findAll({
include: [{
model: model.peopletolists,
}]
})
.then(lists => res.json({
data: lists,
}))
.catch(err => res.json({
error: err,
}))
});
Error: SequelizeEagerLoadingError
A person has many lists and lists have many people. I have not found many things in the Sequelize documentation and not many people complaining about this error, it's generally on ClassMethods, but I'm not even using it.
What's wrong?
This is how I am using it.
ArtistModel.findAll({
where: {
slug: req.params.slug
}, attributes: ['id']
, include: [{
model: Genres,
as: 'ArtistGenre',
required: false,
// attributes: ['id'],
through: {attributes: []},
}],
subQuery: false,
limit: req.query.limit,
offset: req.skip
})
Where Genre is the table that is linked with the Artist table with a many-to-many relationship through ArtistGenre
ArtistGenre Model:
const db = require('../utils/connection');
const Sequelize = require('sequelize');
let ArtistGenre = db.define('artist_genre', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
}
}, {
timestamps: false,
underscored: true
});
ArtistGenre.removeAttribute('id');
module.exports = ArtistGenre;
Artist:
const db = require('../utils/connection');
const Sequelize = require('sequelize');
module.exports = db.define('artist', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING
},
status: {
type: Sequelize.ENUM,
values: ['active', 'inactive'],
defaultValue: 'active'
},
created_at: {
type: 'TIMESTAMP',
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
allowNull: false
},
updated_at: {
type: 'TIMESTAMP',
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
allowNull: false
}
}, {
underscored: true,
timestamps: false
});
Genre Model:
const db = require('../utils/connection');
const Sequelize = require('sequelize');
module.exports = db.define('genre', {
id: {
type: Sequelize.BIGINT(20),
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING
}
}, {
timestamps: false
});
Associations are like the following:
Artist.belongsToMany(models.genre, {as: 'ArtistGenre', through: 'artist_genre', foreignKey: 'artist_id', otherKey: 'genre_id'});
Genre.belongsToMany(models.artist, {as: 'ArtistGenre', through: 'artist_genre', foreignKey: 'genre_id', otherKey: 'artist_id'});
Related
I have two tables, Post and Comments, I am trying to get all posts by userId and also fetch the relevant comments for each post using the following code. I am getting all the posts but nodejs through an error " comment is not associated to post".
Post Table
const {Sequelize, DataTypes} = require('sequelize')
const db = require('../config/db')
const Post = db.define('post', {
id:{
type: DataTypes.INTEGER(255),
autoIncrement: true,
allowNull: false,
primaryKey: true
},
postId:{
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4
},
postText:{
type: DataTypes.TEXT,
allowNull: false
},
totalPostLikes: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: 0
},
totalPostStrikes: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: 0
},
totalPostQuotes: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: 0
},
totalPostShare: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: 0
},
userId:{
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'id'
}
}
},{
freezeTableName: true
})
module.exports = Post
Comments Table
const {Sequelize, DataTypes} = require('sequelize')
const db = require('../config/db')
const Comment = db.define('comment', {
id:{
type: DataTypes.INTEGER(255),
autoIncrement: true,
allowNull: false,
primaryKey: true
},
commentUUID:{
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4
},
commentText:{
type: DataTypes.TEXT,
allowNull: false
},
totalCommentLikes: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: 0
},
totalCommentStrikes: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: 0
},
totalCommentQuotes: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: 0
},
userId:{
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'id'
}
}, postId:{
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: 'post',
key: 'id'
}
}
},{
freezeTableName: true
})
module.exports = Comment
This is how I am creating tables and associations
const db = require('../config/db')
const User = require('./user')
const Post = require('./posts')
const Comments = require('./comments')
User.hasMany(Post)
Post.belongsTo(User)
Post.hasMany(Comments)
Comments.belongsTo(Post)
User.hasMany(Comments)
Comments.belongsTo(User)
db.sync({force: true})
.then((result) =>{
console.log(result)
})
.catch((error) => {
console.log(error)
})
Code to fetch data
router.get('/:id', authenticate, async (req,res) => {
const { id } = req.params
const data = await Post.findAll(
{where: {userId: id},
attributes: [
'postText',
'totalPostLikes',
'totalPostStrikes',
'totalPostQuotes',
'totalPostShare'
],
include:[{model: Comments, attributes:['commentText']}]
})
try{
res.send(data);
} catch({errors}) {
res.status(400).send(errors)
}
})
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
const db = require('../models');
var main = async () => {
try {
const data = await db.post.findAll({
where: { userId: 1 },
attributes: ['postText', 'totalPostLikes', 'totalPostStrikes', 'totalPostQuotes', 'totalPostShare'],
include: [{ model: db.comment, attributes: ['commentText'], as: 'comments' }],
});
console.log(JSON.parse(JSON.stringify(data)));
} catch (e) {
console.log(e);
}
};
main();
I using Sequelize with Node and Express.
I have created two models - User and Task with Many-to-Many associacion
const User = sequelize.define('user', {
id: { type: Sequelize.INTEGER, autoIncrement: true, primaryKey: true, allowNull: false },
username: { type: Sequelize.STRING, allowNull: false, unique: true },
password: { type: Sequelize.STRING, allowNull: false }
})
and
const Task = sequelize.define('task', {
id: { type: Sequelize.INTEGER, autoIncrement: true, primaryKey: true, allowNull: false },
title: { type: Sequelize.STRING, allowNull: false }
})
Many-to-Many associacion
User.belongsToMany(Task, {
through: "user_tasks",
foreignKey: "userId",
otherKey: "taskId"
})
Task.belongsToMany(User, {
through: "user_tasks",
foreignKey: "taskId",
otherKey: "userId"
})
I'm trying to find tasks for user with id userId with following code:
const tasks = await Task.getTasks(
{ through: { where: { userId: request.userId } } }
)
But i have an Error:
TypeError: Task.getTasks is not a function"
If you want one users and their tasks do something like this?
const user = await User.findByPk(request.userId)
const userTasks = await user.getTasks()
I tried to create database with 3 tables: restaurant,restaurant_menu,menu and their relationship is restaurant have many menu and menu can belong to many restarant by sequelize in Nodejs.
restaurant.model.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const restaurant = sequelize.define('restaurant', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
name: DataTypes.STRING,
address: DataTypes.STRING,
phone: DataTypes.STRING,
lat: {
type: DataTypes.DOUBLE,
allowNull: false,
defaultValue: 0
},
lng: {
type: DataTypes.DOUBLE,
allowNull: false,
defaultValue: 0
},
user_owner: {
type: DataTypes.INTEGER,
defaultValue: 0
},
image: {
type: DataTypes.TEXT,
allowNull: false
},
payment_url: {
type: DataTypes.TEXT,
allowNull: false
}
}, {
freezeTableName: true,
timestamps: false
});
restaurant.associate = function (models) {
// associations can be defined here
restaurant.belongsToMany(models.menu, {
through: {
model: models.restaurant_menu
},
foreignKey: 'restaurant_id'
})
};
return restaurant;
};
menu.model.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const menu = sequelize.define('menu', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false
},
name: DataTypes.STRING(50),
description: DataTypes.STRING(500),
image: DataTypes.TEXT
}, {
freezeTableName: true,
timestamps: false
});
menu.associate = function (models) {
// associations can be defined here
menu.belongsToMany(models.restaurant, {
through: {
model: models.restaurant_menu
},
foreignKey: "menu_id"
});
};
return menu;
};
restaurant_menu.model.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const restarant_menu = sequelize.define('restarant_menu', {
restaurant_id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
references: {
model: 'restaurant'
}
},
menu_id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
references: {
model: 'menu'
}
}
}, {
freezeTableName: true,
timestamps: false
});
restarant_menu.associate = function (models) {
// associations can be defined here
};
return restarant_menu;
};
i tried to run migration, but i get error:
Cannot read property 'menu_id' of undefined
How can I fix it?
I believe you are writing old syntax, checkout documentation.
https://sequelize.org/master/manual/advanced-many-to-many.html
I use postgresql/sequelize and findAndCountAll function.
Entry.findAndCountAll({
where: {TitleId: title.id},
include: [
{model: User, as: 'users', attributes: ['username']},
{model: EntryHasLike} // I need to count this. model.
],
offset: 15 * (req.body.page - 1),
limit: 15
}).then(entries => {
res.json({
title: title,
count: entries.count,
entries: entries.rows // [I want to count of likes inside this table]
})
}).catch(err => {}
I'm counting entries with findAndCountAll but I want additionally count of EntryHasLikes model which is the same with Entries.Id.
EntryHasLike model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const EntryHasLike = sequelize.define('EntryHasLike', {
EntryId: {
type:DataTypes.INTEGER,
allowNull: false,
primaryKey: true
},
UserId: {
type:DataTypes.INTEGER,
allowNull: false
},
likeDate: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW
}
},{
timestamps: false
});
EntryHasLike.associate = function(models) {
EntryHasLike.belongsTo(models.User)
EntryHasLike.belongsTo(models.Entry)
};
return EntryHasLike;
};
Entry model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const Entry = sequelize.define('Entry', {
UserId: {
type: DataTypes.INTEGER,
allowNull: false
},
entry: {
type: DataTypes.TEXT,
allowNull: false
},
entryRev: {
type: DataTypes.STRING,
defaultValue: 1
},
entryRefId: {
type: DataTypes.INTEGER,
defaultValue: null
},
entryCondition: {
type: DataTypes.INTEGER,
defaultValue: 1
},
activity: {
type: DataTypes.INTEGER,
defaultValue: 1
},
TitleId: {
type: DataTypes.INTEGER,
allowNull: false
}
}, {});
Entry.associate = function(models) {
Entry.belongsTo(models.Title, {foreignKey: 'TitleId', as: 'titles'})
Entry.belongsTo(models.User, {foreignKey: 'UserId', as: 'users'})
Entry.belongsToMany(models.EntryCat, {through: 'EntryHasCats', as: 'entrycats'})
Entry.belongsToMany(models.EntryTag, {through: 'EntryHasTags', as: 'entrytags'})
Entry.hasMany(models.EntryHasLike)
};
return Entry;
};
I tried many solutions but i couldn't get result. As you see related questions in below but all of about findAll function. My function is findAndCountAll
Counting associated entries with Sequelize
Sequelize 'hasMany' associated(model) count in attributes in query execution
Maybe on client you can take length of Entry.EntryHasLike
setEntry(data) {
this._entry = {
...data,
count: data.EntryHasLike.length
}
}
pInvent.js
module.exports = (sequelize, DataTypes) => {
const PInvent = sequelize.define('prod_invent', {
id: {primaryKey: true, type: DataTypes.INTEGER, autoIncrement: true, allowNull: false, unique: true},
sku_id: {
type: DataTypes.STRING,
allowNull: false,
unique: true
}
});
PInvent.associations = (db) => {
PInvent.belongsToMany(db.cTags, {
as: 'CTags',
through: 'c_prod',
foreignKey: 'prod_id',
otherKey: 'c_id'
});
};
return PInvent
}
pCure.js
module.exports = (sequelize, DataTypes) => {
const PCure = sequelize.define('prod_cure', {
id: {primaryKey: true, type: DataTypes.INTEGER, autoIncrement: true, allowNull: false, unique: true},
c_tag: {type: DataTypes.STRING, allowNull: false, unique: true}
});
PCure.associations = (db) => {
PCure.belongsToMany(db.pInvent, {
as: 'CProd',
through: 'c_prod',
foreignKey: 'c_id',
otherKey: 'prod_id'
});
};
return PCure
}
db.js
db.pInvent = require('../model/pInvent')(sequelize, Sequelize);
db.cTags = require('../model/pCure')(sequelize, Sequelize);
db.cTags.associations(db);
Now when I write the code as shown below :
db.cTags.findAll({
attributes: ['prod_cure.*', 'prod_invent.*', [Sequelize.fn('COUNT', Sequelize.col('prod_invent.id')), 'PostCount']],
include: [{
model: db.pInvent, as: 'CProd'
}]
}).then((data) => {
res.json({info:data})
}).catch((err) => {
res.json({errInfo:err})
})
it gives me the error as shown below :
Unknown table 'prod_invent'
What i want here is , i wanted calculate the count of nested object , but i am not able to do.