I have an issue while trying to add new records into my database.
So I have this code:
const schema = require('./Labels.schema');
const Labels = sequelize.define('labels', {
id: {
type: Sequelize.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: 'id'
},
user: {
type: Sequelize.INTEGER,
allowNull: false,
field: 'user'
},
code: {
type: Sequelize.STRING,
allowNull: false,
field: 'code'
},
name: {
type: Sequelize.STRING,
allowNull: false,
field: 'name'
}
},
{
tableName: 'labels'
timestamps: false
});
Labels.createLabel = async (params) => {
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
params.user = process.env.USER_ID;
const res = joi.validate(params, schema.create);
if(!res) {
Labels.create(params).then(data => {
console.log('test log');
});
} else {
throw new Error(res);
}
};
This is just a basic model of the record that needs to be stored.
I have tried some varients with the create function, sync, async, within try catch. But I just can't get any output what-so-ever. Even if I do a console.log after the create, it doesn't log. So it seems like it gets blocked somehow. That's why I put the sequelize.authenticate to test the connection, but even that doesn't give me any result.
I fairly new to Sequelize, so any help would be highly appreciated!
Related
I don't understand why I get Error: SQLITE_ERROR: no such table: cities even though I created the model with Sequelize. I followed the same code that worked fine last time.
models/cities.js:
const { Sequelize, DataTypes } = require('sequelize');
const db = new Sequelize({
dialect: 'sqlite',
storage: './database.sqlite',
});
const Cities = db.define('cities', {
userId: {
type: DataTypes.STRING,
unique: true,
primaryKey: true,
allowNull: false,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
// ...
busStationsBuilt: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
},
});
module.exports = { Cities };
db-init.js (run manually):
const { Sequelize } = require('sequelize');
const db = new Sequelize({
dialect: 'sqlite',
storage: './database.sqlite',
});
require('./models/cities.js');
const force = process.argv.includes('--force') || process.argv.includes('-f');
db.sync({ force }).then(async () => {
console.log('Database synced.');
db.close();
}).catch(console.error);
commands/found.js:
const { Cities } = require('../models/cities.js');
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('found')
.setDescription('Found your city!')
.addStringOption(option =>
option
.setName('name')
.setDescription('The name of your city!')
.setRequired(true)
),
async execute(interaction) {
const name = interaction.options.getString('name');
const cityAlreadyExists = await Cities.findOne({ where: { userId: interaction.user.id } });
if (!cityAlreadyExists) {
try {
const city = await Cities.create({
userId: interaction.user.id,
name: name,
});
const cityEmbed = new EmbedBuilder()
.setColor(0x73a0d0)
.setTitle(city.name)
.setDescription('Here are your city\'s stats:')
.addFields(
{ name: 'π Happiness:', value: city.happiness },
{ name: 'π§ Population:', value: city.population },
{ name: 'π΅ Balance:', value: city.balance },
{ name: 'πͺ¨ Resources:', value: city.resources },
{ name: 'π¨βπ©βπ§βπ¦ Crowdedness:', value: city.crowdedness },
{ name: 'π Traffic:', value: city.traffic },
{ name: 'π’οΈ Pollution:', value: city.pollution },
);
return interaction.reply({ content: 'Your city has been created!', embeds: [cityEmbed] });
} catch (error) {
await interaction.reply({ content: 'An error occurred while creating your city. Support server: https://discord.gg/XuZNNJbf4U', ephemeral: true });
return console.error(error);
}
} else {
return interaction.reply('Your city already exists!');
}
}
}
I've asked similar questions and everything worked fine then so I'm not sure what went wrong this time. There are no issues/errors when I run db-init.js but I get the error when I run /found.
It looks like you are probably creating multiple databases because the storage path variable is relative to the file where you're creating the Sequelize db:
const db = new Sequelize({
dialect: 'sqlite',
storage: './database.sqlite',
});
I suggest you use an absolute path to your sqlite db file. Check out this answer for some help on getting path info in node.js.
I'm working on an API and have a special problem. When a make a GET request, i received my JSON Data but the server crash with an error :
for (const key of Object.keys(this.constructor._attributeManipulation)) {
TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at Timeout._onTimeout (/Users/quentin/O'Clock/motogpapi/node_modules/sequelize/lib/model.js:83:34)
at listOnTimeout (node:internal/timers:564:17)
at process.processTimers (node:internal/timers:507:7)
I can't undersant origin of this crash. you can find below the code. Is it possible this problem due to as wrong data into db ?
Model team.js:
const { DataTypes, Model } = require("sequelize");
const sequelize = require("../database/client");
class Teams extends Model {}
Teams.init({
name: {
type: DataTypes.STRING,
allowNull: false
},
constructorId: {
type: DataTypes.INTEGER,
allowNull: false
},
isOfficial: {
type: DataTypes.BOOLEAN,
allowNull: false
},
championshipId: {
type: DataTypes.INTEGER,
allowNull: false
},
}, {
sequelize,
tableName: "team"
});
module.exports = Teams;
Model Constructor.js
const { DataTypes, Model } = require("sequelize");
const sequelize = require("../database/client");
class Constructors extends Model {}
Constructors.init({
name: {
type: DataTypes.STRING,
allowNull: false
},
model: {
type: DataTypes.STRING,
allowNull: false
},
engine: {
type: DataTypes.STRING,
allowNull: false
},
}, {
sequelize,
tableName: "constructor"
});
module.exports = Constructors;
Model Index.js i used for associations
const Teams = require("./teams");
const Championships = require("./championships");
const Constructors = require("./constructors");
Constructors.hasMany(Teams, {
foreignKey: "constructorId",
as: "teamsList"
});
Teams.belongsTo(Constructors, {
foreignKey: "constructorId",
as: "constructor"
});
Championships.hasMany(Teams, {
foreignKey: "championshipId",
as: "teamsList"
});
Teams.belongsTo(Championships, {
foreignKey: "championshipId",
as: "championship"
});
module.exports = {
Teams,
Championships,
Constructors
};
The Controller :
const { Teams } = require("../models");
const teamsController = {
async getAllTeams(_, response) {
try {
const teamsList = await Teams.findAll({
include: ["constructor", "championship"]
});
response.json(teamsList);
} catch (error) {
console.log(error);
}
}
};
module.exports = teamsController;
And database/client.js
require("dotenv").config();
const { Sequelize } = require("sequelize");
const sequelize = new Sequelize(process.env.PG_URL, {
define: {
underscored: true
}
});
(async () => {
try {
await sequelize.authenticate();
console.log("Connection has been established successfully.");
} catch (error) {
console.error("Unable to connect to the database:", error);
}
})();
module.exports = sequelize;
I am a nodejs newbie. I have two simple models, User and Story. Here is what I want to do:
I want to retrieve all stories that have {status:"public"} and store it in an array called retrievedStories.
Then for each story I want to use its "user" field (which contains the object id of the user) to lookup the name of the user from User
Then add a new key in each element of retrievedStories called authorName with the name of the user.
Here are the models:
const UserSchema = new mongoose.Schema({
googleId: {
type: String,
required: true
},
displayName: {
type: String,
required: true
},
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
image: {
type: String,
},
createdAt: {
type:Date,
default: Date.now()
}
})
const StorySchema = new mongoose.Schema({
title: {
type: String,
required: true,
trim: true
},
body: {
type: String,
required: true
},
status: {
type: String,
default: 'public',
enum: ['public', 'private']
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
createdAt: {
type:Date,
default: Date.now()
}
})
And here is what I tried, but doesn't work. The stories are retrieved but the authorName is not added. Any help (possibly a better way to do this?) will be highly appreciated!
router.get('/',async (req,res)=>{
try {
const retrievedStories = await Story.find(
{status: "public"}
)
await Promise.all(retrievedStories.map(async (story) =>{
const author = await User.findById(story.user)
story.authorName = author.displayName
}))
return res.json(retrievedStories)
} catch (error) {
console.log(error)
}
})
You can simplify your query by using populate to retrieve User's data:
router.get('/', async (req, res) => {
try {
const retrievedStories = await Story.find({ status: 'public' })
.populate('user')
.exec();
return res.json(retrievedStories);
} catch (error) {
console.log(error);
}
});
You can then access User's displayName data on each StoryΒ by accessing story.user.displayName.
For more information on query population see the official docs.
I'm quite new to node and mongoose. I'm trying to do a project using them, but i'm running into an error while trying to populate. The comment is saved to the Comment schema perfectly, but throws an error when i reference it Organization Schema.Please advise me on what i'm doing wrong. Any form of assistance will be appreciated.
// Post route for comment(on the Organization's profile page)
router.post('/comment/:id', ensureAuthenticated,(req, res) =>{
let id = req.params.id;
console.log(mongoose.Types.ObjectId.isValid(id))
const commentObject = new Comment({
sender: 'Fred kimani',
commentBody: req.body.commentBody
})
console.log(commentObject);
commentObject.save((err, result) =>{
if(err){console.log(err)}
else{
Organization.findByIdAndUpdate(id, {$push: {comments: result}}, {upsert: true}, (err, organization) =>{
if(err){console.log(err)}
else{
console.log('======Comments====')
}
})
res.redirect('/users/organizationprofilepage/:id')
}
})
});
//Organization Schema
const mongoose = require('mongoose');
const OrganizationSchema = new mongoose.Schema({
organization_name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
category: {
type: String,
required: true
},
isApproved: {
type: Boolean,
default: false
},
image:{
type:String,
required:true
},
description: {
type: String,
required: true,
},
comments: [{
type: mongoose.Types.ObjectId,
ref: 'Comment'
}],
},
//{ typeKey: '$type' }
);
OrganizationSchema.statics.getOrganizations = async function () {
try {
const organizations = await this.find();
return organizations;
} catch (error) {
throw error;
}
}
//defines the layout of the db schema
const Organization = mongoose.model('0rganization', OrganizationSchema);
module.exports = Organization;
//Comment schema
const mongoose = require('mongoose');
const CommentSchema = mongoose.Schema({
sender: {
type: String,
},
commentBody: {
type: String,
required: false,
},
date: {
type: Date,
default: Date.now
},
})
CommentSchema.statics.getComments= async function () {
try {
const comments = await this.find();
return comments ;
} catch (error) {
throw error;
}
}
const Comment= mongoose.model('Comment', CommentSchema);
module.exports = Comment;
Try to change the comments type to mongoose.Schema.Types.ObjectId:
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment',
},
],
Try to push the new commend _id into the Organization object after its creation, not the whole object:
commentObject.save((err, result) => {
if (err) {
console.log(err);
} else {
Organization.findByIdAndUpdate(
id,
{ $push: { comments: result._id } }, // <- Change this line
{ upsert: true },
(err, organization) => { }
);
...
}
});
If you just updated the schema you will need to make sure all of the comments are following the new form you created, when you save it will attempt to validate them, that is why an updateOne will work but not await save()
I am using nodeJS, express (4.17.1), sequelize (5.21.4) and mysql (mysql2 v2.1.0) for a current project.
In my database I have three tables Filter, Element and FilterElement. If I query data from database from Filter or Element table separatly I get the result of objects with data. If I want to use "connecting" table FilterElement I get this error {"name":"SequelizeEagerLoadingError"}
EagerLoadingError [SequelizeEagerLoadingError]: filter_element is not
associated to filters_new!
What is wrong with my code?
These are my sequelize objects codes.
Filter.js
const Sequelize = require('sequelize');
const db = require('../config/database');
const Filter = db.define('filters_new', {
Model:{
type: Sequelize.STRING,
primaryKey: true,
allowNull: false
}
},
{
timestamps: false,
freezeTableName: true
}
);
Filter.associate = function(models) {
Filter.belongsToMany(models.Element, {
through: models.FilterElement,
as: 'filter',
foreignKey: 'FilterHousingModel'
});
};
module.exports = Filter;
Element.js
const Sequelize = require('sequelize');
const db = require('../config/database');
const Element = db.define('filter_element', {
idfilter_element:{
type: Sequelize.INTEGER,
primaryKey: true,
allowNull: false
},
ElementName:{
type: Sequelize.STRING,
}
},
{
timestamps: false,
freezeTableName: true
}
);
Element.associate = function(models) {
Element.belongsToMany(models.Filter, {
through: models.FilterElement,
as: 'element',
foreignKey: 'FilterElementId'
});
};
module.exports = Element;
FilterElemnt.js
const Sequelize = require('sequelize');
const db = require('../config/database');
const FilterElement = db.define('filters_new', {
idfilter_filterelement:{
type: Sequelize.STRING,
primaryKey: true,
allowNull: false,
autoincrement: true
},
FilterHousingModel: {
type: Sequelize.STRING
},
FilterElementId: {
type: Sequelize.INTEGER
}
},
{
timestamps: false,
freezeTableName: true
}
);
module.exports = FilterElement;
If I call this function, I do get the desired result of data from database.
listFiltersOnly(req, res) {
return filter.findAll()
.then((filters) => {
res.status(200).send(filters);
})
.catch(err => {
console.log(err);
res.status(400).send(err);
});
}
then if I call function list I get the error mentioned up EagerLoadingError
list(req, res) {
return filter.findAll({
include: [{
model: element,
as: 'element'
}],
})
.then((filters) => {
console.log(filters);
res.status(200).send(filters);
})
.catch(err => {
console.log(err);
res.status(400).send(err);
});
}
Looking for some suggjestions where might be the problem?
#RatulSharker I removed the asociation from the model and added it where the models are implemented in the controller and now I do get some results.
Filter.belongsToMany(FilterElement, {
through: FilterFilterElement,
foreignKey: 'FilterHousingModel'
});
FilterElement.belongsToMany(Filter, {
through: FilterFilterElement,
foreignKey: 'FilterElementId'
});
Thank you #Ratul Sharker