I'm using node.js with express and sequelize and my DB is mysql.
I tried to create a class model as written in the documentation: https://sequelize.org/master/manual/model-basics.html. I was able to connect to the DB, but couldn't figure out how to sync the model with the DB in order to create tables. here is my user model:
const { DataTypes, Model } = require('sequelize');
const connection = require("../server");
export class User extends Model { }
User.init({
id: {
type: DataTypes.BIGINT,
autoIncrement: true,
primaryKey: true,
unique: true,
allowNull: false
},
username: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
userType: {
type: DataTypes.STRING,
allowNull: false,
}
}, {
connection
});
and here is my server.js:
const express = require("express");
const Sequelize = require("sequelize");
const app = express();
const port = 8080;
const connection = new Sequelize("coupons2", "root", "1234", {
host: "localhost",
dialect: "mysql"
})
connection.sync()
.then(() => {
console.log("Connection to DB was successful");
})
.catch(err => {
console.error("Unable to connect to DB", err);
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
})
module.exports = connection;
Thank you!
I think you forgot to require the Sequelize as shown in document you mentioned above
`const {Sequelize, DataTypes, Model } = require('sequelize');
and if you want that it table create automatically by models you can use sequelize.sync in your project
await sequelize.sync({ force: true });
console.log("All models were synchronized successfully.");
User.sync() - creates the table if it doesn't exist (and does nothing if it already exists)
User.sync({ force: true }) - creates the table, dropping it first if it already existed
User.sync({ alter: true }) - checks what is the current state of the table in the database (which columns it has, what are their data types, etc), and then performs the necessary changes in the table to make it match the model.
(async () => {
await sequelize.sync({ alter: true });
})();
I managed to create tables by importing the models to my server.js:
const models = require("./src/models/index");, and using the sync() method.
Related
I use Sequelize in my nodejs.app to load and save data.
To manange Sequelize I use:
(Sample model)
const { Sequelize, DataTypes } = require("sequelize");
const sequelize = require("../config/mysql");
const login = sequelize.define(
"login_bot",
{
login: {
type: DataTypes.STRING,
allowNull: false,
},
// Model attributes are defined here
password: {
type: DataTypes.STRING,
allowNull: false,
},
team: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
timestamps: false,
paranoid: true,
underscored: true,
freezeTableName: true,
}
);
module.exports = login;
The config for this is:
const Sequelize = require("sequelize");
const sequelize = new Sequelize("xxx", "xxx", "xxx", {
host: "xxx.bplaced.net",
dialect: "mariadb",
pool: {
max: 25,
min: 5,
idle: 20000,
evict: 15000,
acquire: 30000,
},
});
sequelize
.authenticate()
.then(() => {
console.log("Connection to database has been established successfully.");
})
.catch((err) => {
console.error("Unable to connect to database:", err);
});
module.exports = sequelize;
In my code I use: as sample
const logindata = await login.findAll({
where: { team: usersdata[0].team },
attributes: ["login", "password"],
raw: true,
});
All works fine. But after some time I get "too many connections" from the server. So I want to ask whether the workflow is wring and I miss to close the DBConnection some where?
I have in all 4 models. All models with "..config/mysql.js" as reference. Do Sequelize open for each model a connection and keeps this open? Or just one connection for the whole app?
In all I just want to have one connection my app is using all the time.
Or do I have to close Sequelize somewhere at each call? Hope to get some hints here because iam lost at this moment.
When your application needs to retrieve data from the database, it creates a database connection. Creating this connection involves some overhead of time and machine resources for both your application and the database. Many database libraries and ORM's will try to reuse connections when possible, so that they do not incur the overhead of establishing that DB connection over and over again. The pool is the collection of these saved, reusable connections that, in your case, Sequelize pulls from. Your configuration of
pool: {
max: 5,
min: 0,
idle: 10000
}
reflects that your pool should:
Never have more than five open connections (max: 5)
At a minimum, have zero open connections/maintain no minimum number of connections (min: 0)
Remove a connection from the pool after the connection has been idle (not been used) for 10 seconds (idle: 10000)
I just start learning how to build a database by using
Im trying to add data to mongoDB and using the .findOne function, but I'm getting this error. is findOne a function in MongoDB?
My Goal is to try to build a full stack mobile application and using mongoDB for database. FrontEnd is flutter. I'm trying to send data from flutter to mongoDB using socket.io.
You might ask yourself why I'm using socket.io if I just need to save data to MongoDB. Well, The application building is a game where multiple users can Join a room and interact with each other.
Here is the versions that using to build the backend "mongoose": "^6.3.3", "socket.io": "^2.3.0"
TypeError: Room.findOne is not a function
at Socket.<anonymous> (/Users/Paul/Documents/server/Index.js:27:45)
at Socket.emit (node:events:390:28)
at /Users/Paul/Documents/server/node_modules/socket.io/lib/socket.js:528:12
at processTicksAndRejections (node:internal/process/task_queues:78:11)
Index.js
Here is my main file
const express = require("express");
var http = require("http")
const app = express();
const port = process.env.PORT || 3000;
var server = http.createServer(app);
const mongoose = require("mongoose");
const Room = require('./models/Room');
//adding socket IO and passing the variable server to it.
var io = require("socket.io")(server);
//middleware
app.use(express.json());
//connecting to MongoDB
const DB = 'mongodb+srv://user:1111#cluster0.tllj9.mongodb.net/?retryWrites=true&w=majority';
mongoose.connect(DB).then(() => {
console.log('Connection Successful!');
}).catch((e) =>{
console.log(e);
})
io.on('connection', (socket) => {
console.log('connected!');
socket.on('create-game', async({nickname, name, numRounds, occupancy}) => {
try {
const existingRoom = await Room.findOne({name});
if(existingRoom){
socket.emit('notCorrectGame', 'Room with that name already exists!');
return;
}
let room = new Room();
const word = getWord();
room.word = word;
room.roomName = roomName;
room.occupnacy = occupnacy;
room.numRounds = numRounds;
let player = {
socketID: socket.id,
nickname,
isPartyLeader: true,
}
room.players.push(player);
room = await room.save();
socket.join(room);
io.to(roomName).emit('updateRoom', room);
} catch (error) {
console.log(error);
}
})
})
server.listen(port, "0.0.0.0", () => {
console.log('Server started and running on port ' + port);
})
Player.js
const mongoose = require('mongoose');
const PlayerSchema = new mongoose.Schema({
nickname: {
type: String,
trim: true,
},
socketID: {
type: String,
},
isPartyLeader: {
type: Boolean,
default: false,
},
points: {
type: Number,
default: 0,
}
})
const playermodel = mongoose.model('Player', PlayerSchema);
module.exports = {playermodel, PlayerSchema}
Room.js
const mongoose = require("mongoose");
const { PlayerSchema } = require("./Player");
var roomSchema = new mongoose.Schema({
word: {
required: true,
type: String,
},
name: {
required: true,
type: String,
unique: true,
trim: true,
},
occupancy: {
required: true,
type: Number,
default: 4
},
maxRounds: {
required: true,
type: Number,
},
currentRound: {
required: true,
type: Number,
default: 1,
},
players: [PlayerSchema],
isJoin: {
type: Boolean,
default: true,
},
turn: PlayerSchema,
turnIndex: {
type: Number,
default: 0
}
});
const gameModel = new mongoose.model('Room', roomSchema);
module.exports = {gameModel, roomSchema};
I honestly can't figure out why I am encountering this error. Maybe, I just need a second eyes to help me out.
Can anyone help with this error? Please and Thank you in advance!
Your error is located here:
io.on('connection', (socket) => {
console.log('connected!');
socket.on('create-game', async({nickname, name, numRounds, occupancy}) => {
try {
//error is here
const existingRoom = await Room.findOne({name});
if(existingRoom){
socket.emit('notCorrectGame', 'Room with that name already exists!');
return;
}
Explanation:
Now, findOne is a function in mongoDB collection/mongoose model. This means const Room must be a collection for you to call Room.findOne()
However, according your index.js file, when you call Room, you aren't grabbing the mongodb collection/mongoose model.
const Room = require('./models/Room');
This is because the export from Room.js is {gameModel, roomSchema} and not just your model, which is what you should be calling the function off of, according to Mongoose documentation. Therefore, const Room = {gameModel, roomSchema}, which has no findOne() function
To fix:
Try object de-structuring the schema and model when you import it like so.
const {gameModel: Room, roomSchema} = require('./models/Room')
Good evening I'm getting this error in my express JS application and not sure how to resolve it.
I'm using an existing mySQL db and trying to retrieve items from my tbl_person table in myDB database. I'm pretty new to this, I'm not too sure what I'm doing incorrect. Some of the examples I'm seeing online is not entirely clear so I need some help.
Here is my sample code:
db.config.js
module.exports = {
HOST: "127.0.0.1",
USER: "root",
PASSWORD: "password",
DB: "myDB"
};
person.model.js
module.exports = (sequelize, DataTypes) => {
const Person = sequelize.define('tbl_person', {
personID: {
type: DataTypes.STRING(36),
field: 'personId',
allowNull: false,
primaryKey: true,
},
accountname: {
type: DataTypes.STRING(50),
field: 'accountname',
allowNull: true,
},
password: {
type: DataTypes.STRING(100),
field: 'password',
allowNull: true,
},
nameprefix: {
type: DataTypes.STRING(20),
field: 'nameprefix',
allowNull: true,
},
firstname: {
type: DataTypes.STRING(50),
field: 'firstname',
allowNull: true,
},
middlename: {
type: DataTypes.STRING(50),
field: 'middlename',
allowNull: true,
},
lastname: {
type: DataTypes.STRING(50),
field: 'lastname',
allowNull: true,
},
})
return Person;
};
person.controller.js
const person = require("../models/person.model.js").Person;
module.exports = {
getPersons(req, res) {
person.findAll({
where: { isActive : 1 },
}).then(person => {
res.status(201).json({
person: person,
success: true,
message: "get person request successful."
});
}).catch(error => {
console.error("get person request failed: ", error);
res.status(500).send({
success: false,
message: "get person request failed: " + error
});
})
}
};
index.js
const person = require("../controllers/person.controller.js");
module.exports = app => {
app.get("/api", (req, res) =>
res.status(200).send({
message: "Welcome to my API!",
})
);
// ========================= Person Routes ========================= //
app.get("/api/person/get", person.getPersons);
};
server.js
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
require("./routes/index.js")(app);
app.get("*", (req, res) => {
res.status(404).send({
status: false,
message: "No matching route!"
});
});
//PORTS
const port = process.env.PORT || 3000;
// set port, listen for requests
app.listen(port, () => {
console.log(`Server is running on port ${port}.`);
});
You should register all models and their associations before using them. And you should use them either from Sequelize instance or from your object holding all registered models.
See my answer here about how to register all models and associations.
I have a MySQL database with a table named 'posts' I'm reading from via FeathersJS and feathers-sequelize. Currently I have a working prototype with the following code which returns the desired result but only to the console, and also the entire contents of the posts table to the /posts route, however I only want to return a specific set of records from the table to /posts.
The table has a column called post_status, in which a post could be 'published' or 'draft'. I only want to return the 'published' records to /posts, but want to achieve this serverside as opposed to /posts?status=published. How can this be achieved?
See below code:
const path = require('path');
const feathers = require('#feathersjs/feathers');
const express = require('#feathersjs/express');
const socketio = require('#feathersjs/socketio');
const Sequelize = require('sequelize');
const service = require('feathers-sequelize');
const sequelize = new Sequelize('sandbox', 'sandbox', 'secretpassword', {
host: 'localhost',
dialect: 'mysql',
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
operatorsAliases: false
});
const Post = sequelize.define('posts', {
post_title: Sequelize.STRING
},
{
timestamps: false,
underscored: true,
});
// Create an Express compatible Feathers application instance.
const app = express(feathers());
// Turn on JSON parser for REST services
app.use(express.json());
// Turn on URL-encoded parser for REST services
app.use(express.urlencoded({ extended: true }));
// Enable REST services
app.configure(express.rest());
// Enable Socket.io services
app.configure(socketio());
app.use(express.errorHandler());
//This works fine to return to the console but not to /posts
Post.findAll({
where: {
post_status: 'published'
}
}) .then(posts => {
console.log(JSON.stringify(posts));
});
//This returns the entire contents of the posts table to /posts
app.use('/posts', service({
Model: Post,
paginate: {
default: 10,
max: 100
},
}));
// Start the server
const port = 3030;
app.listen(port, () => {
console.log(`Feathers server listening on port ${port}`);
});
I tried the 'where' from the findAll method in the service but this did not change the output, or produce any error.
I resolved this by using a where clause in the find method on the service, see below complete code:
const path = require('path');
const feathers = require('#feathersjs/feathers');
const express = require('#feathersjs/express');
const socketio = require('#feathersjs/socketio');
const Sequelize = require('sequelize');
const service = require('feathers-sequelize');
const sequelize = new Sequelize('sandbox', 'sandbox', 'secretpassword', {
host: 'localhost',
dialect: 'mysql',
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
operatorsAliases: false
});
const Post = sequelize.define('posts', {
post_title: Sequelize.STRING,
post_status: Sequelize.STRING
},
{
timestamps: false,
underscored: true,
});
// Create an Express compatible Feathers application instance.
const app = express(feathers());
// Turn on JSON parser for REST services
app.use(express.json());
// Turn on URL-encoded parser for REST services
app.use(express.urlencoded({ extended: true }));
// Enable REST services
app.configure(express.rest());
// Enable Socket.io services
app.configure(socketio());
app.use(express.errorHandler());
const myService = {
find(params) {
let posts = Post.findAll({
where: {
post_status: 'published'
}
});
return Promise.resolve(posts);
},
get(id, params) {},
create(data, params) {},
update(id, data, params) {},
patch(id, data, params) {},
remove(id, params) {},
setup(app, path) {}
}
app.use('/posts', myService);
// Start the server
const port = 3030;
app.listen(port, () => {
console.log(`Feathers server listening on port ${port}`);
});
I have the following two files running on an Express Node.js server:
home.js
var express = require('express')
var sequelize = require('sequelize')
var db = require('../../shared/db.js')
var op = sequelize.Op
var router = express.Router()
router.get('/home', function(req, res, next) {
db.shared.person.findAll({
where: {
email: {
[op.ne]: null
}
},
order: ['id']
}).then(function (person) {
res.locals = {
person: person
}
res.render('home')
})
})
module.exports = router
db.js
var sequelize = require('sequelize')
var config = {
host: 'localhost',
port: 5432,
username: '...',
password: '...',
database: 'postgres',
dialect: 'postgres',
operatorsAliases: false
}
var db = new sequelize(config)
module.exports = {
shared: {
person: db.define('person', {
id: {
type: sequelize.INTEGER,
primaryKey: true
},
name: sequelize.STRING,
email: sequelize.INTEGER
}, { freezeTableName: true , timestamps: false, schema: 'shared' }),
}
}
When I try to run this query, I get an error claiming Unhandled rejection Error: Invalid value { [Symbol(ne)]: null }
What am I doing wrong? I can use $ne and even ne just fine but they've been deprecated and are not entirely safe to use. Furthermore, it's not just [op.ne] - I get this error when I use any conditional like this.
I'm basing this all on this guide so I'm not really sure what I could be doing wrong here.
Unhandled rejection Error: Invalid value might also appear if you didn't setup string aliases like this:
const Op = Sequelize.Op;
const operatorsAliases = {
$eq: Op.eq,
$ne: Op.ne,
...
$any: Op.any,
$all: Op.all,
$values: Op.values,
$col: Op.col
};
const connection = new Sequelize(db, user, pass, { operatorsAliases });
But, better to remove String based aliases from code and use [Op.ne] for example, Sequlize is planning to deprecate them soon.
Sequelize instance in both db.js and home.js are different, this is because node caches a required module based on it path.
To solve this issue you can pass around correct instance in db.js
module.exports = {
shared: {
person: db.define('person', {
id: {
type: sequelize.INTEGER,
primaryKey: true
},
name: sequelize.STRING,
email: sequelize.INTEGER
}, { freezeTableName: true , timestamps: false, schema: 'shared' }),
},
db: db
}
Then finally use operators from that shared instance to do query
var express = require('express')
var sequelize = require('sequelize')
var db = require('../../shared/db.js')
var op = db.db.Op;
var router = express.Router()
router.get('/home', function(req, res, next) {
db.shared.person.findAll({
where: {
email: {
[op.ne]: null
}
},
order: ['id']
}).then(function (person) {
res.locals = {
person: person
}
res.render('home')
})
})
module.exports = router
One more thing, string operators are completely safe to use if you properly sanitize your user inputs. You only need to use secure operators if you are passing un-sanitized user input to Sequelize methods.
More on this topic
http://docs.sequelizejs.com/manual/tutorial/querying.html#operators-security
https://github.com/sequelize/sequelize/issues/8417