I am new to node js environment and currently I am practicing a crud applicaiton
I am using sequelize as ORM and I have used the mvc structure
npm install --save sequelize
$ npm install --save pg pg-hstore
I am using sequelize cli
npm install --save-dev sequelize-cli
npx sequelize-cli init
It is my migration
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('Books', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstName: {
type: Sequelize.STRING
},
lastName: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('Books');
}
};
My Model:
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Books extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
}
};
Books.init({
firstName: DataTypes.STRING,
lastName: DataTypes.STRING,
email: DataTypes.STRING
}, {
sequelize,
modelName: 'Books',
});
return Books;
};
MY Controller:
exports.allBooks = (req,res)=>{
const bookme = Books(**how to pass sequelize**,**how to pass sequelize datatype**)
var booksJSON = bookme.findAll()
res.json(booksJSON)
console.log(JSON.stringify(booksJSON))
}
I am getting the empty response if I pass the datatypes customly by creating a connection manually to database with sequelize and passing that sequelize to the books models
I think that my mistake is in passing these parameters. What and how shoudld I pass to the Books model
I am importing the books model as follows in my controller:
const Books = require('../models/books.js');
also when i ran the bootstraping that created migrations,models,seeding folders it also created a index.js file in models folder
I have tried passing that too in the parameter to Books model but It gave error
index.js in models folder created by sequelize cli package itself
'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;
The error I got when I try to pass this db from index.js to Books model in my controller is:
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
^
TypeError: Class constructor model cannot be invoked without 'new'
What should I pass to the parameter and from where?
I am getting response by using aysnc and await. I used second parameter by importing directly from the package
const Sequelize = require('sequelize')
and for first parameter I used the manually created connection.
but it still doesn't clears my concern of actually what parameters were to pass
Related
I am using Express.js with sequelize
I am trying to get data from table but findALL() method not working
Here , I am sharing my models & controller file
checkout_product model
module.exports = function (sequelize, DataTypes) {
var Checkout_product = sequelize.define(
"Checkout_products",
{
name: {
type: DataTypes.STRING
},
ptice: {
type: DataTypes.STRING
},
image: {
type: DataTypes.STRING
},
quantity: {
type: DataTypes.INTEGER
},
},
);
Checkout_product.associate = function (models) {
Checkout_product.hasMany(models.Product_attribute, {
foreignKey: "product_id",
sourceKey: "id"
});
};
return Checkout_product;
};
product_attribute model
module.exports = function (sequelize, DataTypes) {
var Product_attribute = sequelize.define(
"product_attributes",
{
product_id: {
type: DataTypes.INTEGER
},
attribute_name: {
type: DataTypes.STRING
},
attribute: {
type: DataTypes.STRING
},
price: {
type: DataTypes.STRING
},
},
);
Product_attribute.associate = (models) => {
Product_attribute.belongsTo(models.Checkout_product, {
foreignKey: "product_id",
sourceKey: "id"
});
};
return Product_attribute;
};
models/index.js file
"use strict";
const fs = require("fs");
const path = require("path");
const Sequelize = require("sequelize");
const config = require("./../config/development").database;
let sequelize = new Sequelize(
config.database,
config.username,
config.password,
config
);
let db = {};
fs
.readdirSync(__dirname)
.filter(function(file) {
return file.indexOf(".") !== 0 && file !== "index.js";
})
.forEach(function(file) {
let model = require(path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(function(modelName) {
if ("associate" in db[modelName]) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
Controller
const Checkout_product = require('../models');
module.exports.checkout_product_get = function (req, res) {
Checkout_product.findAll({
include: [ {
model : Product_attributes,
}]
})
.then(checkout_product => {
res.json(checkout_product)
})
}
I am stuck to get data from checkout_product & it's child model product_attribute model,
Everytime I am getting same error : TypeError: Checkout_product.findAll is not a function
const Checkout_product = require('../models').table_name;
Can you try it
You are using the deprecated - legacy way of Sequelize to initialize models. Newer ways with require and extends are available and suggested. Check the docs for more information.
Regarding your code....
You are neither initializing the db structure properly nor using it correctly later...
First your code here in index.js:
.forEach(function(file) {
let model = require(path.join(__dirname, file));
db[model.name] = model;
});
Just loads the model files in the db object. But these files are functions ment to be called with sequelize object as parameter. This is done by providing them to sequelize.import that manages the proper call of the defined model-functions to create the model instances. Check https://sequelize.org/master/manual/models-definition.html
Also after successfully initializing the db, in your controller code, the require('../models') returns the total db object. So if you want to use a specific model as Checkout_product in your case, you have to access it in the object:
const db = require('../models');
db.Checkout_product.findAll()...
I'm using sequelize on my ReactJS application to access my database. Follow the tutorial, below is my sequelize initializer used to load all models and make then available to db:
"use strict";
var fs = require("fs");
var path = require("path");
var Sequelize = require("sequelize");
var basename = path.basename(__filename);
var env = process.env.NODE_ENV || "development";
var config = require(__dirname + "/../config/config.js")[env];
var db = {};
if (config.use_env_variable) {
var sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
var 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 => {
var model = sequelize["import"](path.join(__dirname, file));
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;
This is how a simple model looks like: TestModel.js
export default (sequelize, DataTypes) => {
let TestModel = sequelize.define("TestModel", {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
name: { type: DataTypes.STRING(32), allowNull: false },
description: { type: DataTypes.STRING(256) }
});
return TestModel;
};
And then I can normally use it inside my code:
db.TestModel.find(...);
All running fine, until I need to prepare the production bundle.
I'm using webpack to prepare the production bundle that is delivered as a single file. When doing so, the model files are not any more available for importing at:
fs
.readdirSync(__dirname)
.filter(file => {
return (
file.indexOf(".") !== 0 &&
file !== basename &&
file.slice(-3) === ".js"
);
})
.forEach(file => {
var model = sequelize["import"](path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
.. and then there are no more models available to be used from db, what causes my database access code db.TestModel.find(...); to fail with the following error: TypeError: Cannot read property 'find' of undefined
Naturally no files were imported (there is just my bundle.js) and db does not contain the model definition.
So, I need a way to statically import the models, and here is my try:
import TestModel from "./TestModel.js";
.
.
.
db[TestModel.name].associate(db);
Althought this runs, it does not associate and I'm getting the same error at runtime.
How can I statically associate my models to sequelize db so that I can access then directy as db.ModelName ?
Background
I am working with Sequelize v4.2 and Express v4.15.2 and attempting to setup the models and associate them with one another. I have struggled to find any working v4.x Sequelize examples even after viewing this Express/Sequelize tutorial as well as the v4 migration docs.
Issue
Currently I am receiving the error below when trying to setup my initial models and associations.
/Users/james/Sites/awesome-app/server/node_modules/sequelize/lib/associations/mixin.js:80
if (!target.prototype || !(target.prototype instanceof this.sequelize.Model)) {
TypeError: Cannot read property 'prototype' of undefined
at Function.<anonymous> (/Users/james/Sites/awesome-app/server/node_modules/sequelize/lib/associations/mixin.js:80:16)
Files/Code
My model setup file (index.js) looks like...
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(module.filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
let db = {};
let sequelize = undefined;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable]);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
fs
.readdirSync(__dirname)
.filter((file) => {
return (file.indexOf(".") !== 0) && (file !== 'index.js');
})
.forEach((file) => {
const model = sequelize.import(path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(function(modelName) {
if ('associate' in db[modelName]) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
And my first model (address.js) that fails looks like...
module.exports = function(sequelize, DataTypes) {
var Address = sequelize.define('Address', {
street: DataTypes.STRING,
city: DataTypes.STRING,
state: DataTypes.STRING,
zip: DataTypes.STRING,
});
Address.associate = function(models) {
Address.belongsTo(models.attendeeGroup, {
onDelete: 'CASCADE',
foreignKey: {
allowNull: false
},
});
}
return Address;
};
I am looking to setup my database tables and associate various models with one another. Is there another piece of setup I am missing?
My model I wanted to associate with was incorrectly named/capitalized. I had Address.belongsTo(models.attendeeGroup, { where attendeeGroup was camel case, but in fact it needed to be capitalized like AttendeeGroup which is the name of my other model.
My database was successfully created once I changed this model name.
I'm new in node.
I'm trying to add Sequelize in my simple application with cosign.
config/db.js
var Sequelize = require('sequelize');
var sequelize = new Sequelize('test', 'root', '', {
host: 'localhost',
dialect: 'mysql',
pool: {
max: 5,
min: 0,
idle: 10000
}
});
module.exports = function () {
return sequelize
}
model/user.js
var Sequelize = require('sequelize');
module.exports = function(application, req, res){
var User = sequelize.define('user', {
username: {
type: Sequelize.STRING,
}
}, {
freezeTableName: true // Model tableName will be the same as the model name
});
User.create({ username: 'fnord'})
.then(function() {
console.log('criado!');
})
}
config/server.js
...
consign()
.include('app/routes')
.then('config/db.js')
.then('app/models')
.then('app/controllers')
.into(app);
module.exports = app;
I'm getting the error sequelize is not definedĀ“ onvar User = sequelize.define('user', {`
What I'm doing wrong?
Create an index.js file inside your moldes folder like this:
"use strict";
var fs = require("fs");
var path = require("path");
var Sequelize = require("sequelize");
var sequelize = new Sequelize(global.config.dbConfig.name, global.config.dbConfig.user, global.config.dbConfig.password, {
host: global.config.dbConfig.host,
port: global.config.dbConfig.port,
pool: false
});
var db = {};
fs.readdirSync(__dirname)
.filter(function(file) {
return (file.indexOf(".") !== 0) && (file !== "index.js");
})
.forEach(function(file) {
var model = sequelize.import(path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(function(modelName) {
if ("associate" in db[modelName]) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
module.exports = db;
and in your user.js do something like this:
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define("User", {
username: {
type: DataTypes.STRING
},
{
freezeTableName: true // Model tableName will be the same as the model name
}
});
return User;
}
http://docs.sequelizejs.com/en/1.7.0/articles/express/
You should require sequelize instance into user model
config/db.js
module.exports = sequelize;
model/user.js
var Sequelize = require('sequelize');
var sequelize = require('../config/db.js'); //sequelize instance
module.exports = function(application, req, res){
var User = sequelize.define('user', {
...
The Sequelize-CLI is a very useful tool for projects that use Sequelize. When you download it
npm install -g sequelize-cli
You can then run
sequelize init
The above command will go and write out a few folders for you including a models folder that has the index file that Ricardo created above. This gives some really cool environment configuration as well. Within the new models folder, you can create a new file with your object with the syntax...
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define("User", {
username: {
type: DataTypes.STRING
},
{
freezeTableName: true // Model tableName will be the same as the model name
}
});
return User;
}
While I do like this as a tool. It is key here to notice that Sequelize will go and look for the first argument to the define() method. So we could just write
module.exports = function(sequelize, DataType){
return sequelize.define("User", {
username: {
type: DataTypes.STRING
},
{
freezeTableName: true // Model tableName will be the same as the model name
}
});
I'm following a tutorial which uses sequelize with an express project. Here's the user.js model:
// in models/User.js
module.exports = function(sequelize, DataTypes) {
return sequelize.define('User', {
first_name: DataTypes.STRING,
last_name: DataTypes.STRING,
}, {
instanceMethods: {
countTasks: function() {
// how to implement this method ?
}
}
});
};
Then he uses User in various of ways, for example:
var user = User.build({ first_name: 'John', last_name: 'Doe' });
I understand the code in general, but I don't understand completely why module.exports gets a function with two parameters (sequelize, DataTypes). I haven't seen it initialized anywhere in the code. How is it working then?
If you are following this guide you will see in models/index.js that all model definitions are looped through and passed to seqelize.import().
You will find that this line of code within sequelize.import calls the model's module function and passes a reference to sequelize and DataTypes to the model.
In the tutorial you referenced, the author uses a similar method within models/index.js
> Edit (7/14/2015)
Since the link does not work and I could not find it on their current site, I copied the code from their site using The Wayback Machine. I also updated the second link to point to the 2.0 docs instead of master.
models/index.js
"use strict";
var fs = require("fs");
var path = require("path");
var Sequelize = require("sequelize");
var env = process.env.NODE_ENV || "development";
var config = require(__dirname + '/../config/config.json')[env];
var sequelize = new Sequelize(config.database, config.username, config.password, config);
var db = {};
fs
.readdirSync(__dirname)
.filter(function(file) {
return (file.indexOf(".") !== 0) && (file !== "index.js");
})
.forEach(function(file) {
var model = sequelize["import"](path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(function(modelName) {
if ("associate" in db[modelName]) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;