I'm a beginer at NodeJS, I am Learning Sequelize framework and trying interactive with database. everything is okay until i'm writing insert into table function by sequelize model, Here is My cdoe:
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize("task_management","root","Th#ng123",{
host : "localhost",
dialect : "mysql",
});
//Tao 1 sequelize model
const Task = sequelize.define(
"Task",
{
//Columns in table
name:{
type: Sequelize.STRING, //string
allowNull: false,
},
status: {
type : DataTypes.STRING, //STRING
}
}
)
//Synchronus function <=> Create a new Table in database
const syncModel = async ()=>{
await Task.sync({force: true});
console.log("Task sync model complete");
}
// syncModel();
const createTask = async () => {
// c1
const newTask = Task.build({ name: "Learning NodeJS", status: "OPEN" });
await newTask.save();
// c2
const golangTask = await Task.create({
name: "Learning Golang",
status: "OPEN",
});
};
createTask();
// Check connection
const checkConnect = async ()=>{
try {
await sequelize.authenticate();
console.log("Task check connect complete");
} catch (error) {
console.error("Unable connect Database")
}
}
But the result is with each Create code, in database inserted 3 rows. Like this
enter image description here
What happen and what i can do with this case ? Tell me please
Thank you!
Related
I'm trying to push data to a nested array in mongodb. I'm using mongoose as well.
This is just mock code to see if i can get it working:
User model:
import mongoose from "mongoose";
const CoinSchema = new mongoose.Schema({
coinID: { type: String },
});
const CoinsSchema = new mongoose.Schema({
coin: [CoinSchema],
});
const WatchlistSchema = new mongoose.Schema({
watchlistName: { type: String },
coins: [CoinsSchema],
});
const NameSchema = new mongoose.Schema({
firstName: { type: String },
lastName: { type: String },
username: { type: String },
});
const UserSchema = new mongoose.Schema({
name: [NameSchema],
watchlists: [WatchlistSchema],
test: String,
});
const User = mongoose.model("User", UserSchema);
export default User;
route:
fastify.put("/:id", async (request, reply) => {
try {
const { id } = request.params;
const newCoin = request.body;
const updatedUser = await User.findByIdAndUpdate(id, {
$push: { "watchlists[0].coins[0].coin": newCoin },
});
await updatedUser.save();
// console.dir(updatedUser, { depth: null });
reply.status(201).send(updatedUser);
} catch (error) {
reply.status(500).send("could not add to list");
}
});
request.body // "coinID": "test"
I've tried a lot of different ways to push this data but still no luck. I still get 201 status codes in my terminal which indicates something has been pushed to the DB, but when I check nothing new is there.
Whats the correct way to target nested arrays and push data to them?
It's not perfect but you could get the user document, update the user's watchlist, and then save the updated watchlist like so:
fastify.put("/:id", async (request, reply) => {
try {
const { id } = request.params;
const newCoin = request.body;
// get the user
let user = await User.findById(id);
// push the new coin to the User's watchlist
user.watchlists[0].coins[0].coin.push(newCoin);
//update the user document
const updatedUser = await User.findOneAndUpdate({ _id: id },
{
watchlists: user.watchlists,
},
{
new: true,
useFindAndModify: false
}
);
reply.status(201).send(updatedUser);
} catch (error) {
reply.status(500).send("could not add to list");
}
});
I'm trying to create a "currency system" for a discord bot by following a guide, but when i try to start the bot it says Error: Cannot find module './dbObjects' my app.js code is this:
javascript
New error
The code of objects.js is this the error says: sequelize.import is not a funcion
const Sequelize = require ('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'sqlite',
logging: false,
storage: 'database.sqlite',
});
const Users = sequelize.import('models/Users');
const CurrencyShop = sequelize.import('models/CurrencyShop');
const UserItems = sequelize.import('models/UserItems');
UserItems.belongsTo(CurrencyShop, { foreignKey: 'item_id', as: 'item' });
Users.prototype.addItem = async function(item) {
const userItem = await UserItems.findOne({
where: { user_id: this.user_id, item_id: item.id },
});
if (userItem) {
userItem.amount += 1;
return userItem.save();
}
return UserItems.create({ user_id: this.user_id, item_id: item.id, amount: 1 });
};
Users.prototype.getItems = function() {
return UserItems.findAll({
where: { user_id: this.user_id },
include: ['item'],
});
};
module.exports = { Users, CurrencyShop, UserItems };
the error means that the probleme com from the directory here:
const { Users, CurrencyShop } = require('./dbObjects');
you should change that by
const { Users, CurrencyShop } = require("./models/dbObjects.js');
it should work but i'm not sure! can you add more details on what is the guide you're using?
also, for your code, it's better to use an switch case statement, instead of if, elif
I have used the below code in my API to remove element from an array
deleteCommentLike: async(req, res) => {
const { error } = createComLikeValidation(req.body);
if (!error) {
const { user_id, comment_id } = req.body;
// const likeModel = new likeSchemaModel({user_id: user_id, post_id: post_id});
await commentlikeSchemaModel
.find({ user_id: user_id, comment_id: comment_id })
.remove();
let commenttData = await commentSchemaModel.findById(comment_id);
console.log(commenttData.usersLiked);
commenttData.likes = --commenttData.likes;
commenttData.usersLiked.remove(user_id);
await commenttData.save();
res.status(200).json({ error: false, data: "done" });
} else {
let detail = error.details[0].message;
res.send({ error: true, data: detail });
}
},
In here this one line is not working: commenttData.usersLiked.remove(user_id);. It doesn't give any error but the user_id is not removed from my database.
"use strict";
const mongoose = require('mongoose');
const Joi = require('joi');
var commentSchema = mongoose.Schema({
//other data
usersLiked: [{
type: mongoose.Types.ObjectId,
default: []
}],
//other data
}
var commentSchemaModel = mongoose.model('comments', commentSchema);
module.exports = {
commentSchemaModel,
}
In my mongodb it looks like below
I have alredy tried using it as commenttData.usersLiked.remove(mongoose.Types.ObjectId('user_id'));
but the result is same.
What can be the reason for this and how could I remove the value from the array ?
You should use an update operation:
commenttData.update({_id: mongoose.Types.ObjectId("5f099..")}, {$set: {usersLiked: yourUpdatedUsersLikedArray}})
The error you expect from remove() is missing as you trigger a js noop which is just ignored by the compiler.
Mongoose does not implement the attribute update operation the way you use it.
I am fairly new to this (using sequelize) and everything is new to me. The thing is that I can create and get users through my "users.model.js" but now I want to create a model called "data.model.js" to associate some data to a certain user.
So according to the sequelize docs, my associations should be the following:
Users.hasMany(Data)
Data.belongsTo(Users)
But when sequelize creates my tables, I don't have my foreign key in my data table.
I will share my code with you:
config file (config.js):
const Sequelize = require('sequelize');
const connection = new Sequelize('drglicemia', 'root', '', {
host: 'localhost',
dialect: 'mysql'
});
module.exports = connection;
data.model.js:
const sequelize = require('sequelize');
const db = require('../config/database');
const usersTable = require('./users.model')
let Data = db.define('tabeladados', {
dta: { type: sequelize.DATEONLY },
hora: { type: sequelize.DATE },
indiceglicemia: { type: sequelize.STRING },
insulina: { type: sequelize.STRING },
medicacao: { type: sequelize.STRING },
}, {
timeStamps: false, tableName: 'tabeladados'
});
//associates the dataTable table with the users
Data.associate = () => {
Data.belongsTo(usersTable)
}
module.exports = Data;
users.model.js:
const sequelize = require('sequelize');
const promise = require('bluebird')
const bcrypt = promise.promisifyAll(require('bcrypt'))
const db = require('../config/database');
const dataTable = require('./data.model')
let Users = db.define('utilizadores', {
username: { type: sequelize.STRING },
email: { type: sequelize.STRING },
password: { type: sequelize.STRING },
}, {
timeStamps: false, tableName: 'utilizadores',
});
//encrypts the password before submiting to the database
Users.beforeCreate((user, options) => {
return bcrypt.hash(user.password, 10)
.then(hash => {
user.password = hash;
})
.catch(err => {
throw new Error();
});
});
//validates the password submited by the user with the one encrypted in the database
Users.prototype.validPassword = async (password) => {
return await bcrypt.compare(password, this.password);
}
//associates the users table with the dataTable
Users.associate = () => {
Users.hasMany(dataTable)
}
module.exports = Users;
I believe that when I am trying to associate my tables I am doing something wrong, because I feel that I am doing it the wrong way.
I don't know but everything works besides this.
But it's like what I said in the beginning, I am new to sequelize xD
I think the reason is circular reference. user.model.js requires data.model.js, and data.model.js requires user.model.js.
You need to create an index.js file. Require and make the associations for all models here, then re-export them. E.g.
./models/index.js:
const User = require('./user.model.js');
const Data = require('./data.model.js');
User.hasMany(Data);
Data.belongsTo(User);
module.exports = {User, Data}
service.js or controller.js:
const models = require('./models/index.js');
// use models
await models.User.findAll();
Remove below codes in your model file:
// Remove from user.model.js file
Users.associate = () => {
Users.hasMany(dataTable)
}
// Remove from data.model.js file
Data.associate = () => {
Data.belongsTo(usersTable)
}
I have 2 models, patient & personalInformation.
There is an association such that personalInformation.belongsTo(patient). In my case, the patient primary key or uuid exists as a column in the personalInformation table.
When my API receives a single POST request, I intend to make my controller create a patient entry and personalInformation entry together.
This is my controller code:
// patient.controller.js
const db = require('../../db/databaseConfig');
const Patient = db.patients;
const PersonalInformation = db.personalInformation;
PersonalInformation.Patient = PersonalInformation.belongsTo(Patient);
exports.create = async (req, res) => {
try {
let payload = await req.body;
await console.log('Recevied request: CREATE /api/patients & payload: ', payload);
let newPatientEntry = Patient.create();
let newPInfo = await PersonalInformation.create({
...payload,
patient: newPatientEntry
}, {
include: [{
association: PersonalInformation.Patient,
}]
});
res.send(newPInfo);
} catch (e) {
console.log('error inside create method Patient controller');
throw new Error(e);
}
};
Instead of 1x patient entry and 1x personalInformation entry, the result is 2x patient entries 1x personalInformation. The personalInformation entry has a patient's uuid in the table (the latter of the 2 patients created). I don't know why there are two patient entries.
Here is the relevant nodejs log:
2018-12-05T01:17:57.644499+00:00 app[web.1]: Executing (default): INSERT INTO "patients" ("uuid","createdAt","updatedAt") VALUES ('89290b66-999d-4f10-96b3-4105a26a9450','2018-12-05 01:17:57.583 +00:00','2018-12-05 01:17:57.583 +00:00') RETURNING *;
2018-12-05T01:17:57.645703+00:00 app[web.1]: Executing (default): INSERT INTO "patients" ("uuid","createdAt","updatedAt") VALUES ('9ed075da-757a-457b-b939-ed7e4c7b523a','2018-12-05 01:17:57.612 +00:00','2018-12-05 01:17:57.612 +00:00') RETURNING *;
2018-12-05T01:17:57.659918+00:00 app[web.1]: Executing (default): INSERT INTO "personalInformations" ("id","nameTitle","nameFirst","nameMiddle","nameLast","nameSuffix","nameAlias","dateOfBirth","sex","gender","occupation","deceased","createdAt","updatedAt","patientUuid") VALUES (DEFAULT,'Mr','Robert','Swan','Mueller','II','Bob','1950-12-15 00:00:00.000 +00:00','Male','Man','Special Counsel','False','2018-12-05 01:17:57.594 +00:00','2018-12-05 01:17:57.594 +00:00','9ed075da-757a-457b-b939-ed7e4c7b523a') RETURNING *;
The models are structured as follows:
// patient.model.js
const uuid = require('uuid/v4');
module.exports = (sequelize, Sequelize) => {
const Patient = sequelize.define('patient', {
uuid: {
primaryKey: true,
allowNull: false,
type: Sequelize.UUID,
defaultValue: () => uuid(),
}
});
return Patient;
};
and
// personalInformation.model.js
module.exports = (sequelize, Sequelize) => {
const PersonalInformation = sequelize.define('personalInformation', {
nameFirst: {
type: Sequelize.STRING,
notEmpty: true,
allowNull: false,
},
nameLast: {
type: Sequelize.STRING,
notEmpty: true,
allowNull: false,
},
... etc
... etc
});
return PersonalInformation;
}
Yes it will make 2 entries because you are creating it twice :
let newPatientEntry = Patient.create(); // <----- HERE
let newPInfo = await PersonalInformation.create({
...payload,
patient: newPatientEntry // <----- HERE
}, {
include: [{
association: PersonalInformation.Patient,
}]
});
You can try this :
// let newPatientEntry = Patient.create(); // <----- REMOVE THIS
let newPInfo = await PersonalInformation.create({
...payload,
patient: {} //<---- MAKE THIS BLANK
}, {
include: [{
association: PersonalInformation.Patient,
}]
});