Get data from multiple tables using Seqeulize - node.js

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

Related

Why does associating belongsTo in Sequelize give me this error?

I'm stuck with this problem for quite some time now and I don't know what's wrong with my code I'm trying to associate one table to another but only half of it works any help would be greatly appreciated.
models/companies.js
const DataTypes = require('sequelize');
const sequelize = require('../config/database');
const Users = require('./users');
const Companies = sequelize.define(
'companies',
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
name: {
type: DataTypes.STRING(50),
unique: true,
allowNull: false
},
image_url: {
type: DataTypes.STRING(100),
unique: true
},
created_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
},
updated_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
}
},
{
//Rewrite default behavior of sequelize
timestamps: false,
paranoid: true,
underscored: true
}
);
Companies.hasMany(Users);
Users.belongsTo(Companies);
Companies.sync();
module.exports = Companies;
models/users.js
const DataTypes = require('sequelize');
const sequelize = require('../config/database');
const Users = sequelize.define(
'users',
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
name: {
type: DataTypes.STRING(40),
allowNull: false
},
email: {
type: DataTypes.STRING(60),
allowNull: false,
unique: true
},
password: {
type: DataTypes.STRING(60)
},
role: {
type: DataTypes.STRING(40),
allowNull: false
},
image_url: {
type: DataTypes.STRING(100),
unique: true
},
batch: {
type: DataTypes.STRING(3)
},
major: {
type: DataTypes.STRING(10)
},
company_id: {
type: DataTypes.INTEGER,
allowNull: false
},
created_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
},
updated_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
}
},
{
//Rewrite default behavior of sequelize
timestamps: false,
paranoid: true,
underscored: true
}
);
Users.sync();
module.exports = Users;
Then after I try to run this code below
const Companies = require('./database/models/companies');
const Users = require('./database/models/Users');
//Relation 1: Company and Users
Companies.findAll({ include: [ Users ] }).then((res) => console.log(res));
Users.findAll({ include: [ Companies ] }).then((res) => console.log(res));
it gives me this error:
(node:4893) UnhandledPromiseRejectionWarning: SequelizeEagerLoadingError: companies is not associated to users!
I've tried a couple of solutions online but it didn't help in this case.
BelongsTo means one to one relationship while a company may have multiple users (meaning, calling BelongsTo after hasMany collide!).
For more: https://sequelize.org/master/manual/assocs.html

sequelize association N:M Table and 1:N Table

I am using sequelize, mysql for node.js!
Have a question and post it.
First, to create a review table with N: M relationship between user table and store table!
Please refer to the ReviewImage Table, which is a 1: N relationship with the Review Table.
For synchronization, please refer to the Review Table and ReviewImage Table.
I don't know what the problem is even if I browse the sequelize API documentation!
Have you ever done the wrong database design?
Should I design a review image table?
const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const db = {};
const sequelize = new Sequelize(
config.database, config.username, config.password, config);
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.User = require('./UserModel')(sequelize, Sequelize);
db.Store = require('./StoreModel')(sequelize, Sequelize);
db.Review = require('./reviewModel')(sequelize, Sequelize);
db.ImageReview = require('./imageReviewModel')(sequelize, Sequelize);
/** N:M User : Store (Review) */
db.User.belongsToMany(db.Store, { through: db.Review});
db.Store.belongsToMany(db.User, { through: db.Review});
/** 1:N review : imageReview */
db.Review.hasMany(db.ImageReview);
db.ImageReview.belongsTo(db.Review);
module.exports = db;
// userModel.js
module.exports = (sequelize, DataTypes) => {
return sequelize.define('User',{
userPlatformType:{
type: DataTypes.STRING(50),
},
userNickname:{
type: DataTypes.STRING(50),
allowNull: false,
unique : true,
},
customerEmail: {
type: DataTypes.STRING(100),
allowNull: false,
unique: true,
},
userPassword:{
type: DataTypes.STRING(200),
allowNull: false,
},
salt:{
type: DataTypes.STRING(200),
},
userPhoneNumber:{
type: DataTypes.STRING(45),
},
userDateOfBirth:{
type: DataTypes.DATEONLY,
},
userWeddingDay:{
type: DataTypes.DATEONLY,
},
userProfile: {
type: DataTypes.STRING(200),
allowNull: true,
},
}, {
freezeTableName: true,
});
};
// storeModel.js
module.exports = (sequelize, DataTypes) => {
return sequelize.define('Store',{
storeName:{
type: DataTypes.STRING(50),
},
storeCategory: {
type: DataTypes.STRING(100),
allowNull: false,
unique: true,
},
storeAddress:{
type: DataTypes.STRING(150),
allowNull: false,
unique : true,
},
storeLatitude:{
type: DataTypes.STRING(45),
},
storeLongtitude:{
type: DataTypes.STRING(45),
},
storeCondition: {
type: DataTypes.STRING(200),
allowNull: false,
},
storePhoneNumber:{
type: DataTypes.STRING(200),
allowNull: false,
},
storeProfile:{
type: DataTypes.STRING(200),
},
storeWifi:{
type: DataTypes.STRING(45),
},
storePost:{
type: DataTypes.STRING(100),
},
storeItem:{
type: DataTypes.STRING(100),
},
storeIntro:{
type: DataTypes.STRING(100),
},
storeLike: {
type: DataTypes.INTEGER,
defaultValue: 0,
},
storeRating: {
type: DataTypes.INTEGER,
defaultValue: 0,
},
storeIsJoin: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
}, {
freezeTableName: true,
});
};
//ReviewModel.js
module.exports = (sequelize, DataTypes) => {
return sequelize.define('Review',{
reviewWriter :{
type: DataTypes.STRING(50),
allowNull: false,
},
reviewContent :{
type: DataTypes.STRING(200),
allowNull: false,
},
reviewGrade : {
type: DataTypes.INTEGER,
allowNull: false,
},
reviewIsDeclare : {
type: DataTypes.BOOLEAN,
allowNull: false,
},
}, {
freezeTableName: true,
});
};
//ReviewImage.js
module.exports = (sequelize, DataTypes) => {
return sequelize.define('ImageReview',{
reviewImageUrl :{
type: DataTypes.STRING(200),
allowNull: false,
},
}, {
freezeTableName: true,
});
};

Cannot read property 'menu_id' of undefined

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

How to associated two models in node JS

I'm trying to make this connection between these two tables, but I'm not getting it and it's giving the following error: "UnhandledPromiseRejectionWarning: SequelizeEagerLoadingError: cfg_user is not associated to dn_coluna!"
follows below the controllers and models that I am using to inner join
This is my cfg_user.js
const sequelizePaginate = require("sequelize-paginate");
module.exports = function(sequelize, DataTypes) {
const cfg_user = sequelize.define("cfg_user", {
'id_cfg_user': {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
'id_cfg_grupo': {
type: DataTypes.INTEGER(11),
allowNull: true
},
'nome': {
type: DataTypes.CHAR(100),
allowNull: true
},
'email': {
type: DataTypes.CHAR(100),
allowNull: true
},
'arquivo': {
type: DataTypes.CHAR(255),
allowNull: false
},
'senha': {
type: DataTypes.CHAR(32),
allowNull: true
}
},{
tableName: "cfg_user",
freezeTableName: true,
timestamps: false
});
sequelizePaginate.paginate(cfg_user);
return cfg_user;
};
This is my dn_coluna.js
const sequelizePaginate = require("sequelize-paginate");
const cfg_user = require("./cfg_user");
module.exports = function(sequelize, DataTypes) {
const dn_coluna = sequelize.define("dn_coluna", {
'id_dn_coluna': {
type: DataTypes.INTEGER(10),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
'id_cfg_user': {
type: DataTypes.INTEGER(10),
allowNull: false
},
'coluna': {
type: DataTypes.CHAR(255),
allowNull: false
},
'frase': {
type: DataTypes.CHAR(255),
allowNull: true,
},
'resumo': {
type: DataTypes.CHAR(255),
allowNull: true,
},
'url': {
type: DataTypes.CHAR(255),
allowNull: true
},
'arquivo': {
type: DataTypes.CHAR(255),
allowNull: true
},
'arquivo_topo': {
type: DataTypes.CHAR(255),
allowNull: true
},
'arquivo_bg': {
type: DataTypes.CHAR(255),
allowNull: true
},
'ordem': {
type: DataTypes.INTEGER(11),
allowNull: true
},
'destaque':{
type: DataTypes.TINYINT(1),
allowNull: true
},
'libera': {
type: DataTypes.TINYINT(1),
allowNull: true
}
},{
tableName: "dn_coluna",
freezeTableName: true,
timestamps: false
});
sequelizePaginate.paginate(dn_coluna);
return dn_coluna;
};
this is my Controller
const { dn_coluna } = require("../models");
const { cfg_user } = require("../models");
module.exports = {
async index(req, res){
const colunas = await dn_coluna.findAll({
include: [{
model: cfg_user,
attributes: []
}],
attributes: ['id_cfg_user'],
})
.then(colunas => {
return res.status(200).json(colunas);
});
},
};
Your answer lies in associations. You are not properly associating your tables together. Here is a link to the documentation. I am unsure of the type of relationship that cfg_user and dn_coluna have so I can't show you how to write the association but the below may help.
Remove the below from dn_coluna.js
'id_cfg_user': {
type: DataTypes.INTEGER(10),
allowNull: false
}
Add in to dn_coluna.js (just above sequelizePaginate.paginate(dn_coluna);):
dn_coluna.associate = (models) => {
dn_coluna.hasMany(models.cfg_user, {foreignKey: 'cfg_user_id'})
}
In cfg_user.js add (just above sequelizePaginate.paginate(cfg_user);):
cfg_user.associate = (models) => {
cfg_user.belongsTo(models.dn_coluna)
}
The above will create a one to many relationship between dn_coluna and cfg_user.

findall many to many sequelize

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

Resources