Sequelize model.create is not a function - mysql

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

Related

Graphql using Sequelize + mysql: Database Variable always empty

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.

Cannot create a mysql entry using nodejs and mysql

I have a simple node service that should add a db entry to my mysql Users table.
With console log statements, I confirmed that the endpoint is receiving the correct parameter values from the client for username, password and email. However, the entry is not added to my db. I also see in the node logs that the mySQL query appears to ultimately include question marks rather than the actual parameter values. What am I missing here?
My create user query is defined in this file, usercontroller.js
const db = require("../models");
const User = db.users;
const Op = db.Sequelize.Op;
const util = require("util");
var AWS = require("aws-sdk");
const { resolve } = require("path");
const { rejects } = require("assert");
var s3 = new AWS.S3({
accessKeyId: "************",
secretAccessKey: "*************",
region: "us-east-2",
});
// Create and Save a new User
exports.create = (req, res) => {
console.log("creating user");
const username = req.body.username;
const password = req.body.password;
const email = req.body.email;
console.log('username: ' + username)
console.log('password: ' + password)
console.log('email: ' + email)
User.create({
username: username,
email: email,
password: password,
})
.then((data) => {
console.log('data: ' + JSON.stringify(data))
res.send(data);
})
.catch((err) => {
res.status(500).send({
message: err.message || "Some error occurred while creating user.",
});
});
};
This is the output log of calling the create user function above...
creating user
username: A
password: c
email: B
Executing (default): INSERT INTO `Users` (`id`,`username`,`password`,`email`,`createdAt`,`updatedAt`) VALUES (DEFAULT,?,?,?,?,?);
Here is my index.js file...
const dbConfig = require("../config/db.config.js");
const Sequelize = require("sequelize");
const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
host: dbConfig.HOST,
dialect: dbConfig.dialect,
operatorsAliases: false,
pool: {
max: dbConfig.pool.max,
min: dbConfig.pool.min,
acquire: dbConfig.pool.acquire,
idle: dbConfig.pool.idle
}
});
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.users = require("./users.model.js")(sequelize, Sequelize);
module.exports = db;
and user.model.js...
module.exports = (sequelize, Sequelize) => {
const User = sequelize.define("User", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
firstname: {
type: Sequelize.STRING
},
lastname: {
type: Sequelize.STRING
},
username: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
skill_level: {
type: Sequelize.STRING
},
location: {
type: Sequelize.STRING
},
country: {
type: Sequelize.STRING
},
instagram_username: {
type: Sequelize.STRING
},
facebook_username: {
type: Sequelize.STRING
},
profile_image: {
type: Sequelize.STRING
},
country_code: {
type: Sequelize.STRING
},
age: {
type: Sequelize.INTEGER
},
bio: {
type: Sequelize.TEXT
}
});
return User;
};

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.

No Sequelize instance passed for discordjs

https://github.com/qaiswaz/ticket
hear is the code please help me I've bean searching for a solution for a week now.
every time i try to run the bot hear is what it says
bot is online
Executing (default): SELECT 1+1 AS result
connected to DB
Error: No Sequelize instance passed
at Function.init (C:\Users\qaisw\OneDrive\Desktop\ALL FILES\discording\ticket\node_modules\sequelize\lib\model.js:921:13)
at Function.init (C:\Users\qaisw\OneDrive\Desktop\ALL FILES\discording\ticket\models\TicketConfig.js:5:20)
at C:\Users\qaisw\OneDrive\Desktop\ALL FILES\discording\ticket\bot.js:13:22
at processTicksAndRejections (internal/process/task_queues.js:88:5)
bot.js
require('dotenv').config();
const { Client } = require('discord.js');
const client = new Client({ partials: ['MESSAGE', 'REACTION'] });
const db = require('./database');
const Ticket = require('./models/Ticket');
const TicketConfig = require('./models/TicketConfig');
client.once('ready', () => {
console.log('bot is online');
db.authenticate()
.then(() => {
console.log('connected to DB');
Ticket.init(db);
TicketConfig.init(db);
Ticket.sync();
TicketConfig.sync();
}).catch((err) => console.log(err));
});
client.on('message', async message => {
if (message.author.bot || message.channel.type === 'dm') return;
if (message.content.toLowerCase() ==='?setup' && message.guild.ownerID === message.author.id) {
try {
const filter = (m) => m.author.id === message.author.id;
message.channel.send('please enter the message id for this ticket');
const msgId = (await message.channel.awaitMessages(filter, { max: 1})).first().content;
console.log(msgId)
const fetchMsg = message.channel.messages.fetch(msgId);
message.channel.send('please enter the category id for this ticket');
const categoryId = (await message.channel.awaitMessages(filter, { max: 1})).first().content;
console.log(categoryId)
const categoryChannel = client.channels.catche.get(categoryId);
message.channel.send('please enter all of the roles that have access to tickets');
const roles = (await message.channel.awaitMessages(filter, {max: 1})).first().content.split(/,\s*/);
if (fetchMsg && categoryChannel) {
for (const roleId of roles)
if (!message.guild.roles.cache.get(roleId)) throw new Error('role does not exist');
const ticketConfig = await TicketConfig.create({
messageId: msgId,
guildId: message.guild.id,
roles: json.stringify(roles),
parentId: categoryChannel.id
});
message.channel.send('saved config to db');
}else throw new error('invaild fields');
}catch (err) {
}
}
});
client.login(process.env.BOT_TOKEN);
database.js
const { Sequelize } = require('sequelize');
module.exports = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASS, {
dialect: 'mysql',
host: process.env.DB_HOST
});
*models/Ticket.js
const { DataTypes, Model } = require('sequelize');
module.exports = class Tickets extends Model {
static init(sequelize) {
return super.init( {
ticketId: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
channelId: {
type: DataTypes.STRING,
},
guildId: {
type: DataTypes.STRING,
},
resolved:{
type: DataTypes.BOOLEAN,
},
closedMessageId:{
type: DataTypes.STRING,
},
authorId:{
type: DataTypes.STRING,
},
},
{
sequelize: sequelize,
modelName: 'Ticket'
})
}
}
models/TicketConfig.js
const { DataTypes, Model } = require('sequelize');
module.exports = class TicketConfig extends Model {
static init(sequelize) {
return super.init({
messegeId: {
type: DataTypes.STRING,
primaryKey: true
},
guildld: {
type: DataTypes.STRING
},
roles: {
type: DataTypes.STRING
},
parentld: {
type: DataTypes.STRING
},
sequelize: sequelize,
modelName: 'TicketConfig',
})
}
}
I added sequelizeInstance while define model
*models/Ticket.js
const { DataTypes, Model } = require('sequelize');
const sequelizeInstance = require('./database');
module.exports = class Tickets extends Model {
static init(sequelize) {
return super.init( {
ticketId: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
channelId: {
type: DataTypes.STRING,
},
guildId: {
type: DataTypes.STRING,
},
resolved:{
type: DataTypes.BOOLEAN,
},
closedMessageId:{
type: DataTypes.STRING,
},
authorId:{
type: DataTypes.STRING,
},
},
{
sequelize: sequelizeInstance, // <-
modelName: 'Ticket'
})
}
}
models/TicketConfig.js
const { DataTypes, Model } = require('sequelize');
const sequelizeInstance = require('./database')
module.exports = class TicketConfig extends Model {
static init(sequelize) {
return super.init({
messegeId: {
type: DataTypes.STRING,
primaryKey: true
},
guildld: {
type: DataTypes.STRING
},
roles: {
type: DataTypes.STRING
},
parentld: {
type: DataTypes.STRING
},
sequelize: sequelizeInstance, // <-
modelName: 'TicketConfig',
})
}
}

TypeError: Cannot read property 'findOne' of undefined while using sequelize in node

I am getting belo mentioned error when trying to make user authentication using passport-local and sequelize for MySQL. When running server it is creating new table in SQL if not already, but as soon as I hit sign up button it is showing error.
Error:
TypeError: Cannot read property 'findOne' of undefined
at Strategy._verify (E:\Web Development\node-SQL-Sequelize-passport-local\config\passport\passport.js:19:13)
at Strategy.authenticate (E:\Web Development\node-SQL-Sequelize-passport-local\node_modules\passport-local\lib\strategy.js:88:12)
at attempt (E:\Web Development\node-SQL-Sequelize-passport-local\node_modules\passport\lib\middleware\authenticate.js:361:16)
at authenticate (E:\Web Development\node-SQL-Sequelize-passport-local\node_modules\passport\lib\middleware\authenticate.js:362:7)
My server.js look like :
app.use(passport.initialize());
app.use(passport.session());
//Models
var models = require("./app/models");
//Routes
var authRoute = require('./app/routes/auth.js')(app,passport);
require('./config/passport/passport.js')(passport, models.user);
//Sync Database
models.sequelize.sync().then(function() {
console.log('Nice! Database looks fine')
}).catch(function(err) {
console.log(err, "Something went wrong with the Database Update!")
});
app.get('/', function(req, res) {
res.send('Welcome to Passport with Sequelize');
});
My user.js file:
module.exports = function(sequelize, Sequelize) {
var User = sequelize.define('userInfo', {
id: {
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstname: {
type: Sequelize.STRING,
notEmpty: true
},
lastname: {
type: Sequelize.STRING,
notEmpty: true
},
username: {
type: Sequelize.TEXT
},
about: {
type: Sequelize.TEXT
},
email: {
type: Sequelize.STRING,
validate: {
isEmail: true
}
},
password: {
type: Sequelize.STRING,
allowNull: false
},
last_login: {
type: Sequelize.DATE
},
status: {
type: Sequelize.ENUM('active', 'inactive'),
defaultValue: 'active'
}
});
return User;
}
My passport.js file :
var bCrypt = require('bcrypt-nodejs');
module.exports = function(passport, user) {
var User = user;
var LocalStrategy = require('passport-local').Strategy;
passport.use('local-signup', new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},function(req, email, password, done) {
var generateHash = function(password) {
return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null);
};
User.findOne({
where: {
email: email
}
}).then(function(user) {
if (user)
{
return done(null, false, {
message: 'That email is already taken'
});
} else
{
var userPassword = generateHash(password);
var data =
{
email: email,
password: userPassword,
firstname: req.body.firstname,
lastname: req.body.lastname
};
User.create(data).then(function(newUser, created) {
if (!newUser) {
return done(null, false);
}
if (newUser) {
return done(null, newUser);
}
});
}
});
}
));
}
Review this example: github.com/sequelize/express-example. In particular models/index.js for models load.
That way is handled in that example is:
require('./config/passport/passport.js')(passport, models.userInfo);
Because "userInfo" is defined in your model user.js: