Graphql using Sequelize + mysql: Database Variable always empty - mysql

I have gone through many different solutions to overcome this problem. But nothing seems to be working.
My Files:
database.js
const {Sequelize} = require("sequelize");
var db = {}
const sequelize = new Sequelize('ETconnect', 'root', 'D5kIzmJB', {
host: '10.10.10.11',
port: '3306',
dialect: 'mysql',
define: {
freezeTableName: true,
},
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000,
},
// <http://docs.sequelizejs.com/manual/tutorial/querying.html#operators>
operatorsAliases: false,
})
let models = [
require('./models/users.js'),
]
// Initialize models
models.forEach(model => {
const seqModel = model(sequelize, Sequelize)
db[seqModel.name] = seqModel
})
// Apply associations
Object.keys(db).forEach(key => {
if ('associate' in db[key]) {
db[key].associate(db)
}
})
db.sequelize = sequelize
db.Sequelize = Sequelize
exports.db;
models/users.js
const {Sequelize} = require('sequelize');
module.exports = function(sequelize, DataTypes) {
return sequelize.define('users', {
id: {
autoIncrement: true,
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
primaryKey: true
},
name: {
type: DataTypes.STRING(50),
allowNull: false
},
email: {
type: DataTypes.STRING(50),
allowNull: false,
unique: "email"
},
password: {
type: DataTypes.STRING(255),
allowNull: false
},
profileimage: {
type: DataTypes.STRING(45),
allowNull: true
}
}, {
sequelize,
tableName: 'users',
timestamps: false,
indexes: [
{
name: "PRIMARY",
unique: true,
using: "BTREE",
fields: [
{ name: "id" },
]
},
{
name: "email",
unique: true,
using: "BTREE",
fields: [
{ name: "email" },
]
},
]
});
};
models/init-models.js
var DataTypes = require("sequelize").DataTypes;
var _users = require("./users");
function initModels(sequelize) {
var users = _users(sequelize, DataTypes);
return {
users,
};
}
module.exports = initModels;
module.exports.initModels = initModels;
module.exports.default = initModels;
Graphql/users.js
const {gql} = require("apollo-server-express");
const db = require("../database");
//import { gql } from 'apollo-server-express'
//import * as db from '../database'
exports.typeDefs = gql`
extend type Query {
users: [User]
user(id: ID!): User
}
type User {
id: ID!
name: String
email: String
}
`
exports.resolvers = {
Query: {
users: async () => console.log(db),
user: async (obj, args, context, info) =>
db.users.findByPk(args.id),
},
}
Everytime I use the users query in the Apollo test environment I get a log which says that the Database variable is empty.
Output: {}
Can anybody tell me what I did wrong? Does it not connect to the Database? Because we have a similar application that does perfectly fine.
I would really appreciate the help.

Related

TypeError: models.leaves.getAllEmpoyees is not a function

I am writing a function in Schema Model for getting Data with a query. The query is working fine, but unfortunately i am getting an error regarding Function - getAllEmpoyees() not found. For Reference - my sequelize version is - 6.15.0 . I am new to Node.js. Can anyone help me out yrr, Thanks in Advance!
const Sequelize = require('sequelize');
module.exports = function(sequelize, DataTypes) {
return sequelize.define('leaves', {
id: {
autoIncrement: true,
type: DataTypes.BIGINT.UNSIGNED,
allowNull: false,
primaryKey: true
},
employee_id: {
type: DataTypes.INTEGER,
allowNull: false
},
leave_type_id: {
type: DataTypes.INTEGER,
allowNull: false
},
leave_reason: {
type: DataTypes.STRING(255),
allowNull: false
},
remark: {
type: DataTypes.STRING(255),
},
status: {
type: DataTypes.STRING(255),
allowNull: false
},
created_by: {
type: DataTypes.INTEGER
}
},
{
sequelize,
tableName: 'leaves',
timestamps: true,
indexes: [
{
name: "PRIMARY",
unique: true,
using: "BTREE",
fields: [
{ name: "id" },
]
},
]
},
getAllEmpoyees = function() {
var query = "select * from leaves as l join leave_types as lt on l.leave_type_id=lt.id";
return sequelize.query(query, { type: sequelize.QueryTypes.SELECT});
},
);
};
const express = require('express');
const router = express.Router();
var path = require('path');
var root_path = path.dirname(require.main.filename);
var models = require(root_path + '/models');
var moment = require("moment");
router.get('/getallemployeeLeaves', (req, res) => {
console.log("All Fetched");
models.leaves.getAllEmpoyees().then(function (data) {
console.log("");
if (data.length > 0) {
res.json({
status: 200,
data: data
})
} else {
res.json({
status: 400,
})
}
})
})

Adding Many to Many Data Sequelize

Case: I have 2 tables; one for users and one for assignments. A user can have many assignments and an assignment can be assigned to many users. I have a form in the frontend to add assignment and assign the users for the assignment and I am really confused on how to add the assignment and user to the joint table 'user_assignment'. Can someone point where I am having the mistake? Also for this, I refer to Advanced M:N Associations.
I also attach my code for the Users and Assignments model, and other relevant code parts.
user.model.js
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define("users", {
firstName: {
type: DataTypes.STRING,
allowNull: false,
},
lastName: {
type: DataTypes.STRING,
allowNull: false,
},
department: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
role: {
type: DataTypes.STRING,
allowNull: false,
},
});
return User;
};
assignment.model.js
module.exports = (sequelize, DataTypes) => {
const Assignment = sequelize.define("assignments", {
title: {
type: DataTypes.STRING,
allowNull: false,
},
department: {
type: DataTypes.STRING,
allowNull: false,
},
urgency: {
type: DataTypes.STRING,
allowNull: false,
},
assignmentBegin: {
type: DataTypes.STRING,
allowNull: false,
},
assignmentEnd: {
type: DataTypes.STRING,
allowNull: false,
},
description: {
type: DataTypes.STRING,
allowNull: false,
},
});
return Assignment;
};
database/index.js
...
db.user = require("../models/user.model")(sequelize, Sequelize);
db.assignment = require("../models/assignment.model")(sequelize, Sequelize);
...
db.user.belongsToMany(db.assignment, {
through: "user_assignment",
as: "assignments",
foreignKey: "userId",
});
db.assignment.belongsToMany(db.user, {
through: "user_assignment",
as: "users",
foreginKey: "assignmentId",
});
...
assignment.controller.js
const db = require("../database");
const Assignment = db.assignment;
const User = db.user;
exports.create = async (req, res) => {
const {
participant,
title,
department,
urgency,
assignmentBegin,
assignmentEnd,
description,
} = req.body;
await Assignment.create({
title: title,
department: department,
urgency: urgency,
assignmentBegin: assignmentBegin,
assignmentEnd: assignmentEnd,
description: description
}).then(async result => {
for (i = 0; i < participant.length; i++) {
const user = await User.findByPk(participant[i])
// console.log(user.id)
await UserController.addAssignment(user.id, result.id);
// await UserController.addAssignment(2, 1)
}
}).catch(err => {
res.json({ message: "ERROR WHILE CREATING ASSIGNMENT!" });
console.log(">>> ERROR WHILE CREATING ASSIGNMENT!")
});
}
Any pointers on what I should do would be great!
I'd recommend you define the model associations inside each of the model files. Also you should hash/encrypt your passwords before saving them to the DB, you can use the .comparePassword() function outside of the model in a controller when logging in etc.
models/User.js
const Promise = require('bluebird')
const bcrypt = Promise.promisifyAll(require('bcrypt'))
function hashPassword (user) {
const SALT_FACTOR = 12
if (!user.changed('password')) {
return;
} else {
user.setDataValue('password', bcrypt.hashSync(user.password, SALT_FACTOR))
}
}
module.exports = User = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
firstName: {
type: DataTypes.STRING,
allowNull: false,
},
lastName: {
type: DataTypes.STRING,
allowNull: false,
},
department: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
role: {
type: DataTypes.STRING,
allowNull: false,
},
{
hooks: {
beforeCreate: hashPassword,
beforeUpdate: hashPassword
}
})
User.associate = models => {
User."Association type here"(models."Model to associate",
{Options (For many to many add your "through" table here)}
)
// Example:
User.belongsToMany(models.Assignment, {
through: "UserAssignment"
})
}
User.prototype.comparePassword = function (password) {
return bcrypt.compareSync(password, this.password)
}
return User
}
And in the associated Model (models/Assignment.js):
module.exports = Assignment = (sequelize, DataTypes) => {
const Assignment = sequelize.define('Assignment', {
title: {
type: DataTypes.STRING,
allowNull: false,
},
department: {
type: DataTypes.STRING,
allowNull: false,
},
urgency: {
type: DataTypes.STRING,
allowNull: false,
},
assignmentBegin: {
type: DataTypes.STRING,
allowNull: false,
},
assignmentEnd: {
type: DataTypes.STRING,
allowNull: false,
},
description: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
timestamps: false
})
Assignment.associate = models => {
Assignment.belongsToMany(models.User, {
through: "UserAssignment"
})
}
return Role
}
The joint table (models/UserAssignment.js):
module.exports = UserAssignment = (sequelize, DataTypes) => {
const UserAssignment = sequelize.define('UserAssignment', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
}
},
{
timestamps: false
})
return UserAssignment
}
And finally my index.js file (models/index.js), it programatically adds the models to the DB:
'use strict';
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
fs
.readdirSync(__dirname)
.filter(file => {
return (file.indexOf('.') !== 0)
&& (file !== basename)
&& (file.slice(-3) === '.js');
})
.forEach(file => {
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
As an extra note, you can shorten down your createAssignment function in your controller by doing this instead:
const {
participant,
title,
department,
urgency,
assignmentBegin,
assignmentEnd,
description,
} = req.body;
await Assignment.create({
title: title,
department: department,
urgency: urgency,
assignmentBegin: assignmentBegin,
assignmentEnd: assignmentEnd,
description: description
}).then(async result => {
result.addUsers(participant)
}).catch(err => {
res.json({ message: "ERROR WHILE CREATING ASSIGNMENT!" });
console.log(">>> ERROR WHILE CREATING ASSIGNMENT!")
});
Hope this helps, if not lmk ill try to help some more.

Sequelize model.create is not a function

I'm new to sequelize and trying to set it up for my new project. I checked some answers on this, but couldnt get past my error. Can someone point out how to fix this.
models/index.js
// Database service
// Connects to the database
const { Sequelize } = require('sequelize');
const path = require('path');
const sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASS, {
host: process.env.DB_HOST,
dialect: 'mysql',
logging: process.env.QUERY_LOGGING == "true" ? console.log : false,
pool: {
max: 10,
min: 0,
acquire: 30000,
idle: 10000
}
});
module.exports = sequelize
models/users.js
const sequelize = require("./index")
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('Users', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING
},
profileURL: {
type: DataTypes.STRING
},
emailId: {
type: DataTypes.STRING,
allowNull: false
},
passwordHash: {
type: DataTypes.STRING,
allowNull: false
},
street: {
type: DataTypes.STRING
},
city: {
type: DataTypes.STRING,
allowNull: false
},
phone: {
type: DataTypes.STRING
},
newsletter: {
type: DataTypes.STRING
},
visibility: {
type: DataTypes.BOOLEAN,
defaultValue: true
},
},{
});
return User;
};
And finally, I'm importing the User model in my service file like below:
const User = require("../models/users")
const createUser = async(req) => {
const {firstName, lastName, profileURL, emailId, passwordHash, street, city, phone, newsletter, visibility} = req.body
const user = await User.create({
firstName,
lastName,
profileURL,
emailId,
passwordHash,
street,
city,
phone,
newsletter,
visibility
})
console.log("new user==>>", user)
return
}
module.exports = { createUser }
However, I get the following error.
TypeError: User.create is not a function
Can someone point out what I could be doing wrong? I realize it could be something minor.
Thank you
You export a function that registers the User model and not the model itself. So you just need to call it passing sequelize instance and DataTypes somewhere like database.js where you will register all models and their associations or directly in models/index.js:
const UserModelConstructor = require("../models/users")
const { DataTypes } = require("sequelize");
...
const UserModel = UserModelConstructor(sequelize, DataTypes);
module.exports = {
sequelize,
User: UserModel
}
You can look at how to register multiple models and association in my other answer here
Please don't forget to remove this line
const sequelize = require("./index")
from models/users.js

Sequelize Error: you must use the 'as' keyword to specify the alias of the association you want to include. - node.js

I am making a web application which is similar to 'Twitter'.
When I ran the server,
'user is associated to user multiple times. To identify the correct association,
You must use the 'as' keyword to specify the alias of the association you want to include.'
<- this message appeared.
I applied 'as' keyword for the relationship between 'followers' and 'followings'.
but the error message kept on appearing.
I'm sure that I did something wrong in someway, but I can't figure out what exactly it is.
can somebody help me?
models/index.js
'use strict';
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
fs
.readdirSync(__dirname)
.filter(file => {
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
})
.forEach(file => {
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.User = require('./user')(sequelize, Sequelize);
db.Post = require('./post')(sequelize, Sequelize);
db.Hashtag = require('./hashtag')(sequelize, Sequelize);
db.User.hasMany(db.Post); //1 : n
db.Post.belongsTo(db.User);
// m: n
db.Post.belongsToMany(db.Hashtag, { through: 'PostHashtag' });
db.Hashtag.belongsToMany(db.Post, { through: 'PostHashtag' });
// I use alias here *****
db.User.belongsToMany(db.User, {
foreignKey: 'followingId',
as: 'Followers',
through: 'Follow',
});
db.User.belongsToMany(db.User, {
foreignKey: 'followerId',
as: 'Followings',
through: 'Follow',
});
module.exports = db;
models/user.js
module.exports = (sequelize, DataTypes) => (
sequelize.define('user', {
email: {
type: DataTypes.STRING(40),
allowNull: true,
unique: true,
},
nick: {
type: DataTypes.STRING(15),
allowNull: false,
},
password: {
type: DataTypes.STRING(100),
allowNull: true,
},
provider: {
type: DataTypes.STRING(10),
allowNull: false,
defaultValue: 'local',
},
snsId: {
type: DataTypes.STRING(30),
allowNull: true,
},
}, {
timestamps: true,
paranoid: true,
})
);
models/post.js
module.exports = (sequelize, DataTypes) => (
sequelize.define('user', {
email: {
type: DataTypes.STRING(40),
allowNull: true,
unique: true,
},
nick: {
type: DataTypes.STRING(15),
allowNull: false,
},
password: {
type: DataTypes.STRING(100),
allowNull: true,
},
provider: {
type: DataTypes.STRING(10),
allowNull: false,
defaultValue: 'local',
},
snsId: {
type: DataTypes.STRING(30),
allowNull: true,
},
}, {
timestamps: true,
paranoid: true,
})
);
models/hashtag.js
module.exports = (sequelize, DataTypes) => (
sequelize.define('hashtag', {
title: {
type: DataTypes.STRING(15),
allowNull: false,
unique: true,
},
}, {
timestamps: true,
paranoid: true,
})
);
I think this will solve your problem you have to create a table follower than associate it with user table with following and follower alias and use it to query follower and following
follower Model
module.exports = (sequelize, datatypes) => {
sequelize.define('follower', {
_id: {
type: datatypes.integer,
allownull: false,
primarykey: true,
autoincrement: true
},
userid: {
type: datatypes.integer,
allownull: false
},
followingid: {
type: datatypes.integer,
allownull: false
}
});
}
association
db.follower.belongsTo(db.user, {
as: 'following',
foreignkey: 'followingid'
});
db.follower.belongsto(db.user, {
as: 'follower',
foreignkey: 'userid'
});
query to get follower
follower.findall({
where: {
followingid: userid
},
attributes: ['_id'],
include: [{
model: user, attributes:
['fullname', 'username', '_id', 'picture'],
as: 'follower'
}]
})

Sequelize association cant work on my code,please

im recently to sequelize.
I have 2 table, data_track and car_detail. i want to try associate that 2 table but it never associated.
it's always return error
SequelizeEagerLoadingError: car_detail is not associated to data_track!
please help me
both table have same primary key column name
data_track.js
const Sequelize = require('sequelize')
const gps_status_track = require("./../../configs/gps_status_track")
const data_track = gps_status_track.define('data_track',
{
car_id:{
type:Sequelize.INTEGER,
primaryKey:true
},
off_time:{
type:Sequelize.INTEGER,
},
nopol:{
type:Sequelize.STRING
},
wilayah:{
type:Sequelize.STRING
},
status:{
type:Sequelize.STRING
},
o_path:{
type:Sequelize.STRING
},
keterangan:{
type:Sequelize.STRING
},
last_update:{
type:"TIMESTAMP"
},
},
{
createdAt:'created_at',
updatedAt:'updated_at',
deletedAt:'deleted_at',
freezeTableName: true,
}
)
data_track.associate = (models)=>{
data_track.belongsTo(models.car_detail,{foreignKey:'car_id',as:'dataTrack'})
}
module.exports = data_track
car_detail.js
const Sequelize = require('sequelize')
const gps_status_track = require("./../../configs/gps_status_track")
const car_detail = gps_status_track.define('car_detail',
{
car_id:{
type:Sequelize.INTEGER,
primaryKey:true
},
nopol:{
type:Sequelize.STRING
},
wilayah:{
type:Sequelize.STRING
},
o_path:{
type:Sequelize.STRING
},
},
{
createdAt:'created_at',
updatedAt:'updated_at',
deletedAt:'deleted_at',
freezeTableName: true,
}
)
car_detail.associate = (models)=>{
car_detail.hasOne(models.data_track,{foreignKey:'car_id',as:'carDetail'})
}
module.exports = car_detail
Thanks!
Try doing it this way:
DataTrack.js:
module.exports = (sequelize, Sequelize) => {
const DataTrack = sequelize.define('data_track',
{
car_id: {
type: Sequelize.INTEGER,
primaryKey: true
},
off_time: {
type: Sequelize.INTEGER,
},
nopol: {
type: Sequelize.STRING
},
wilayah: {
type: Sequelize.STRING
},
status: {
type: Sequelize.STRING
},
o_path: {
type: Sequelize.STRING
},
keterangan: {
type: Sequelize.STRING
},
last_update: {
type: "TIMESTAMP"
},
},
{
createdAt: 'created_at',
updatedAt: 'updated_at',
deletedAt: 'deleted_at',
freezeTableName: true,
});
return DataTrack;
}
CarDetail.js:
module.exports = (sequelize, Sequelize) => {
const CarDetail = sequelize.define('car_detail',
{
car_id: {
type: Sequelize.INTEGER,
primaryKey: true
},
nopol: {
type: Sequelize.STRING
},
wilayah: {
type: Sequelize.STRING
},
o_path: {
type: Sequelize.STRING
},
},
{
createdAt: 'created_at',
updatedAt: 'updated_at',
deletedAt: 'deleted_at',
freezeTableName: true,
}
);
return CarDetail;
}
db.config.js:
const env = require('./env.js')
const Sequelize = require('sequelize')
const sequelize = new Sequelize(env.database, env.username, env.password, {
host: env.host,
dialect: env.dialect
})
const db = {}
db.Sequelize = Sequelize
db.sequelize = sequelize
db.data_track = require('../models/DataTrack')(sequelize, Sequelize)
db.car_detail = require('../models/CarDetail')(sequelize, Sequelize)
db.car_detail.hasOne(db.data_track, { foreignKey: { name: 'cars_id', allowNull: false } })
db.data_track.belongsTo(db.car_detail, { foreignKey: { name: 'cars_id', allowNull: false } })
module.exports = db
You're defining association is not correct.
car_detail.hasOne(models.data_track,{foreignKey:'carIDFK', sourceKey: 'cardDetailPKId', as:'carDetail'})
In the data track model, the association will look like.
data_track.belongsTo(models.car_detail,{foreignKey:'carIDFK', targetKey: 'cardDetailTablePKId'})