Sequelize foreing key is not creating - javascript

I try to create a relation between 2 tables with Sequelize in NodeJS for MariaDB.
I have 2 tables order and local, the table order needs one of the information of the table local.
The order table contains information about an order (id: 1, type: Jacket, color: blue, tracking_number: TR123)
The table local contains information about the place where the order is stored (address: 20 rue madeline, city: Paris)
I tried to link the two tables but it does not work, the foreing key is not created
models/order.js
module.exports = (sequelize, DataTypes) => {
const Order = sequelize.define('order', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
trackingNumber: {
type: DataTypes.STRING,
allowNull: false
},
type: {
type: DataTypes.STRING(50),
allowNull: false
},
color: {
type: DataTypes.STRING(50),
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false
},
tel: {
type: DataTypes.STRING(10),
allowNull: false
}
}, {
timestamps: true,
createdAt: true,
updatedAt: 'updateTimestamp'
})
Order.associate = function (models) {
Order.hasOne(models.local);
}
return Order;
}
models/local.js
module.exports = (sequelize, DataTypes) => {
const Local = sequelize.define('local', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
adress: {
type: DataTypes.STRING,
allowNull: false
},
informations_about: {
type: DataTypes.STRING,
allowNull: false
},
contact: {
type: DataTypes.STRING,
allowNull: false
},
city: {
type: DataTypes.STRING,
allowNull: false
},
zip: {
type: DataTypes.STRING(5),
allowNull: false
},
}, {
timestamps: true,
createdAt: true,
updatedAt: 'updateTimestamp'
})
return Local;
}
app.js
// Imports
const express = require('express')
const morgan = require('morgan')
const db = require('./database')
const sequelize = require('./database').sequelize;
var apiRouter = require('./apiRouter.js').router;
var helmet = require('helmet');
const app = express()
const port = process.env.PORT || 3000;
// Init server
app.use(morgan('combined'))
// Parser config
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
// Security API
app.use(helmet());
app.disable('x-powered-by');
app.use(({ res }) => {
res.status(404).json({ message: "404 Not Found" })
})
db.sequelize.authenticate()
.then(_ => console.log("La connexion à bien été établie."))
.catch(error => console.log(`error ${error}`))
db.sequelize.sync({ force: true })
.then(_ => {
console.log("Base de donnée synchronisée.")
app.use('/api/', apiRouter);
})
app.listen(port, () => {
console.log("Server is up and listening in " + port)
})
database.js
const fs = require('fs')
const path = require('path')
const { Sequelize } = require('sequelize')
const db = {}
const models = path.join(__dirname, 'models') // correct it to path where your model files are
const sequelize = new Sequelize(
'',
'',
'',
{
host: 'localhost',
dialect: 'mariadb',
dialectOptions: {
useUTC: false, // for reading from database
},
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
logging: false
}
)
var basename = path.basename(module.filename)
fs
.readdirSync(models)
.filter(function (file) {
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js')
})
.forEach(function (file) {
const model = require(path.join(__dirname + '/models', file))(sequelize, Sequelize.DataTypes)
db[model.name] = model
})
Object.keys(db).forEach(function (modelName) {
if (db[modelName].associate) {
db[modelName].associate(db)
}
})
db.Sequelize = Sequelize // for accessing static props and functions like Op.or
db.sequelize = sequelize // for accessing connection props and functions like 'query' or 'transaction'
module.exports = db
Despite the associate function in the model/order.js it does not work, I have no key in my order table

You have to manually call all associate functions in order to register associations between models and only after all models are already registered in the Sequelize instance. You can look at my other answer to see how you can do it.
And please show the content of database module and then I probably correct my answer or append more useful tips.

Related

My nodejs query not creating user in my database with sequelize and not returning error

I'm trying to create an API with Node.JS , express and MySQL for that I decided to use an ORM Sequelize. In short, I wanted to do this properly and avoid going through the CLI to do what I have to do.
The problem being that when I try to send a POST request from insomnia to my API it can't create a user for me, I have the impression that it doesn't understand what I'm sending to it and I I'm quite lost because I don't understand where I messed up..
Roughly I think that my problem comes from the fact that I do not know how to link the different sources of .js file between them..
I'll leave you my code maybe it's going to be obvious in any case I've already torn out a lot of hair 😤
app.js:
const { urlencoded } = require('express');
const express = require('express');
const path = require('path');
const userRoutes = require('./routes/user');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content, Accept, Content-Type, Authorization');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
next();
})
app.use('/api/auth', userRoutes);
module.exports = app;
models/index.js:
const db = require('./database');
const User = require ('./user.js');
const Vehicle = require('./vehicle');
const Service = require('./service');
(async () => {
try {
await db.authenticate();
console.log('Connection has been established successfully.');
await db.sync();
// await db.sync({ alter: true, force: true});
// console.log('All models were synchronized successfully.');
} catch (error) {
console.error('Unable to connect to the database:', error);
} finally {
db.close();
}
})()
User.belongsToMany(Vehicle, { through: 'UserVehicles' });
Vehicle.belongsToMany(User, { through: 'UserVehicles' });
module.exports = { User, Vehicle, Service };
models/database.js:
const { Sequelize } = require('sequelize');
require('dotenv').config();
const db = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASSWORD, {
host: process.env.DB_HOST,
dialect: process.env.DB_DIALECT,
},
);
module.exports = db;
models/user.js
const { DataTypes, Model } = require('sequelize');
const sequelize = require('./database.js');
const validator = require('validator');
class User extends Model {}
User.init({
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
unique: true,
},
firstName: {
type: DataTypes.STRING,
allowNull: false,
},
lastName: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
phoneNumber: {
type: DataTypes.INTEGER,
allowNull: false,
unique: true,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
birthday: {
type: DataTypes.DATE,
allowNull: true,
},
fidelityPoint: {
type: DataTypes.INTEGER,
defaultValue: 0,
},
group: {
type: DataTypes.INTEGER,
defaultValue: 0,
validate: {
isInt: true,
},
}
}, {
sequelize,
modelName: 'User',
tableName: 'Users',
timestamps: true,
updatedAt: false,
});
module.exports = sequelize.model('User');
console.log('User ->', User === sequelize.models.User);
controllers/user.js:
const validator = require('validator');
const bcrypt = require('bcrypt');
const { User } = require('../models/index');
exports.signup = (req, res, next) => {
let regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}/;
let firstName = req.body.firstName;
let lastName = req.body.lastName;
let email = req.body.email;
let phoneNumber = req.body.phoneNumber;
let password = req.body.password;
let birthday = req.body.birthday;
let fidelityPoint = req.body.fidelityPoint;
let group = req.body.group;
console.log('User ->', User);
if(email == null || phoneNumber == null || password == null || birthday == null) {
console.log('Creditentials ->', email, phoneNumber, password, birthday);
return res.status(401).json({ error: 'Champs vide' })
}
(async () => {
const user = {
firstName: firstName,
lastName: lastName,
email: email,
phoneNumber: phoneNumber,
password: password,
birthday: null,
fidelityPoint: fidelityPoint,
group: group,
}
await User.create(user)
.then(() => res.status(201).json({ message: 'Utilisateur créé avec succès !' }))
.catch(error => res.status(400).json({ message: 'Impossible de créer cet utilisateur', error }))
console.log('user instanceof User ->', user instanceof User);
})()
console.log('Signup User -> ', User);
}
If anyone can enlighten me that would be really nice of him 🙏
Alright, so I finally solved my problem. I had in fact this error which does not appear from my catch in the JSON but by adding the error in the console it sent me back:
Error: ConnectionManager.getConnection was called after the connection manager was closed!
Infact I closed the connection to the database before the work could be done so I removed the
finally {
db.close()
}
from my index.js and it works fine!

mongoDB collection creation

i have a problem with adding a collection into my database in mongodb atlas.
I have managed to import this collection before but i accidentally deleted it and now i can't upload it again. there is no error in my terminal. There for i don't know what is wrong with my code.. (image of my code and terminal are attached below)
There is anyone who might know why is this can happen?
EDIT
I tried to open a new database and my all the collections was imported to it and once again, only the product collection doesn't
//////////////////////////////////
/* require('dotenv').config({ path: '/.env' }) */
const path = require('path')
require('dotenv').config({ path: path.resolve(__dirname, '..', '.env') })
console.dir(process.env.MONGO_URI)
const mongoose = require('mongoose')
const connectDB = async () => {
try {
mongoose.connect(process.env.MONGO_URI, {
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
})
console.log('MongoDB connection SUCCESS')
} catch (error) {
console.error('MongoDB connection FAIL')
process.exit(1)
}
}
console.dir(process.env.MONGO_URI)
module.exports = connectDB
////////////////////////////////////////////////////////////////
require('dotenv').config()
const productsData = require('./data/products')
const connectDB = require('./config/db')
const Product = require('./models/product')
connectDB()
const importData = async () => {
try {
/* Product.deleteMany({}) */
Product.insertMany(productsData)
console.dir('Data Imported Successfuly')
process.exit()
} catch (error) {
console.log(error)
console.error('Error Ocured In Imported Data Process', error)
process.exit(1)
}
}
importData()
my model schema
const mongoose = require('mongoose')
const products = require('../data/products')
const productSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
countInStock: {
type: Number,
required: true,
},
imageUrl: {
type: String,
required: true,
},
})
module.exports = mongoose.model('Products', productSchema)
my code and terminal image
Product.insertMany(productsData) returns a promise, but you aren't waiting for that promise to finish before exiting the process. Add an await before it and you should be okay.
Try this to create your schema instead
const { Schema } = mongoose;
const productSchema = new Schema({
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
countInStock: {
type: Number,
required: true,
},
imageUrl: {
type: String,
required: true,
},
})
const Product = mongoose.model("Product", productSchema);
Product.createCollection();

Sequelize failing to create a table with the error "Executing (default): SELECT 1+1 AS result"

Thank you for taking the time to help out. When running my server I am getting a message "Executing (default): SELECT 1+1 AS result". My tables are not being created. How do I fix this error? I am using the technologies MySQL, Sequelize, JavaScript, Express, and Node.
Connection.js (I have checked the .env and the information is accurate)
const Sequelize = require('sequelize');
require('dotenv').config();
const sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PW, {
host: 'localhost',
dialect: 'mysql',
port: 3306
});
module.exports = sequelize;
Schema.sql
DROP DATABASE IF EXISTS events_db;
CREATE DATABASE events_db;
Customer model
const { DataTypes, Model } = require('sequelize');
const sequelize = require('../config/connection');
class Customer extends Model {}
Customer.init(
{
uuid: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV1,
primaryKey: true,
allowNull: false,
unique: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true,
}
},
phone: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
notEmpty: true,
is: /^[\+]?[(]?\d{3}[)]?[-\s\.]?\d{3}[-\s\.]?\d{4,6}$/im
}
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true
}
},
address: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
notEmpty: true
}
}
},
{
sequelize,
freezeTableName: true,
underscored: true,
modelName: 'customer'
}
);
module.exports = Customer;
Model index.js
const Customer = require('./Customer');
const Event = require('./Event');
const EventType = require('./EventType');
const Reservation = require('./Reservation');
Customer.hasMany(Reservation, {foreignKey: { allowNull: false }});
Event.hasMany(Reservation, {foreignKey: { allowNull: false }});
Event.hasOne(EventType, {foreignKey: { allowNull: false }});
Event.hasOne(Customer, {foreignKey: { allowNull: false }});
module.exports = { Customer, Event, EventType, Reservation };
Server.js
const express = require('express');
const sequelize = require('./config/connection');
const app = express();
const PORT = process.env.PORT || 3001;
const routes = require('./routes');
app.use(express.json());
app.use(express.urlencoded({
extended: true
}));
app.use(routes);
sequelize.sync({ force: false }).then(() => {
app.listen(PORT, () => {
console.log(`App is listening on port ${PORT}`);
});
});
Imported models into server.js file. Did not need to call the variable. This allowed for sequelize to "see" my models. When implementing a controller or GraphQL, this import can be removed.

how to fix getting undefined for model classes using sequelize?

I am learning to use sequelize with my Next.js app.I set up the sequelize, used the cli to generate migrations, created the model (user) , and when i try to test it, going to the http://localhost:3000/api/app . i get an error -> Cannot read property 'findAll' of undefined.
my model class is coming up as undefined. anyone has any idea?
*director structure
MyApp
...
> database
- db.js
> migrations
> models
-user.js
> node_modules
> pages
> api
- app.js
db.js
const Sequelize = require('sequelize');
const db = new Sequelize('mydb', 'root', 'pass', {
host: "localhost",
port: 3306,
dialect: 'mysql',
operatorsAliases:false,
logging: function () {},
pool: {
max: 5,
min: 0,
idle: 10000
},
dialectOptions: {
socketPath: "/var/run/mysqld/mysqld.sock"
},
define: {
paranoid: true
}
});
db.authenticate().then(() => {
console.log('connection error');
}).catch(err => {
console.log('Connection successful');
});
module.exports = db;
model/User.js
module.exports = (sequelize, DataTypes) => {
const user = sequelize.define("User", {
id : {
type: DataTypes.INTEGER(11),
allowNull: false,
autoIncrement:true,
primaryKey:true
},
firstName : {
type: DataTypes.STRING(50),
allowNull: false
}
lastName : {
type: DataTypes.STRING(50),
allowNull: false
},
created: {
type: 'TIMESTAMP',
defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'),
allowNull: false
},
updated:{
type: 'TIMESTAMP',
defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'),
allowNull: false
}
});
return user;
};
pages/api/app.js
const models = require('../../models')
export default (req, res) => {
models.user.findAll(); //error => Cannot read property 'findAll' of undefined
};
You define uppercase User in the User.js file, so you have to use it uppercase:
const models = require('../../models');
export default async (req, res) => {
const users = await models.User.findAll();
console.log(users);
};

Sequelize connection with Nodejs

I am facing issue on connection of SEQUELIZE(mysql) with NodeJs. Though connection is established but models are not properly configured. I have use this approach --
./config/sequelize-conn.js
'use strict';
var sequelize = function (config, Sequelize) {
var sql = new Sequelize(config.mysql.db, config.mysql.user, config.mysql.pass, {
host: config.mysql.host,
dialect: 'mysql', //|'sqlite'|'postgres'|'mssql'
pool: {
max: 5,
min: 0,
idle: 10000
},
//logging: true,
underscored: true
});
sql
.sync({force: true})
//.authenticate()
.then(function () {
console.log('Connection has been established successfully with mysql.');
}, function (error) {
console.log('Connection with mysql failed.', error);
});
return sql;
};
module.exports = sequelize;
//server.js
var sequelize = require('sequelize');
var sqlConnection = require('./config/sequelize-conn')(config, sequelize);
I wish to directly use model this way ..
models/HotelGroup.js
var Sequelize = require('sequelize');
var sequelize = require('../../config/sequelize-conn');
var HotelGroup = Sequelize.define('hotel_chains', {
id: {
type: Sequelize.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
hotel_name: {
type: Sequelize.STRING,
allowNull: false
},
hotel_code: {
type: Sequelize.STRING,
allowNull: false
},
status: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: '1'
}
}, {
tableName: 'hotel_chains',
timestamps: false,
paranoid: true // Model tableName will be the same as the model name
});
module.exports = HotelGroup;
Its giving me error that sequelize.define is not a function.
Though connection is establishing but when I try to access any model in service file using require. It breaks with this error message. Where I am doing wrong.
I think you need to use the instance of sequelize, not the class. So sequelize.define not Sequelize.define.
Also, you need to instantiate it properly: var sequelize = new Sequelize(...)

Categories