sails js getting data from database without schema definition in model - mysql

I am new to SailsJs. I have a MySQL database with 123 tables with lots of fields. Now i want to use that database in my sails application. When i need to get data from any table i need to declare fields name, type etc in model like below
module.exports = {
tableName: 'Mytable',
adapter: 'someMysqlServer',
migrate: 'safe',
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
id: {
type: 'number',
required:true
},
name: {
type: 'string',
required: true
}
}
};
Now I don't want to declare all the fields in model as i have so many tables/fields. So how can i select/insert/update data without this.

var connection = mysql.createConnection({
host: sails.config.connections.yourDbConnetion.host,
user: sails.config.connections.yourDbConnetion.user,
password: sails.config.connections.yourDbConnetion.password,
database: sails.config.connections.yourDbConnetion.database
});
YourFunction: function (req,res) {
connection.query('YOUR SQL QUERY ', function (err, result) {
if (err)
return res.send(err);
.........
});
}

Related

Sequelize error "Unknown column in 'field list'" during CREATE for One-to-Many Association

I have been using the following tutorial to learn how to implement one-to-many relationship in Sequelize where a Tutorial has many Comment and Comment belongs to a Tutorial: https://www.bezkoder.com/sequelize-associate-one-to-many/
While I have the code modeling what is documented for setting up the relationship between the two models, I receive the following error during creating the Comment model:
Unknown column 'tutorialId' in 'field list'
Additionally, I receive the following SQL output:
Executing (default): INSERT INTO `comments` (`id`,`name`,`text`,`createdAt`,`updatedAt`,`tutorialId`) VALUES (DEFAULT,?,?,?,?,?);
app.js
const tutorialsRouter = require('./routes/api/tutorials');
const commentsRouter = require('./routes/api/comments');
app.use('/api/tutorials', tutorialsRouter);
tutorialsRouter.use('/:tutorialId/comments', commentsRouter);
/models/index.js
db.tutorials = require("./tutorial.model")(sequelize, Sequelize);
db.comments = require("./comment.model")(sequelize, Sequelize);
db.tutorials.hasMany(db.comments, { as: "comments" });
db.comments.belongsTo(db.tutorials, {
foreignKey: "tutorialId",
as: "tutorial",
});
/models/comment.model.js
module.exports = (sequelize, DataTypes) => {
const Comment = sequelize.define('comment', {
name: {
type: DataTypes.STRING,
},
text: {
type: DataTypes.STRING,
},
});
return Comment;
}
/routes/comments.js
const comments = require('../../controllers/comments.controller');
const router = require('express').Router({ mergeParams: true });
router.post('/', comments.create);
module.exports = router;
/controllers/comments.controller.js
const db = require('../models');
const Comment = db.comments;
exports.create = (req, res) => {
...
Comment.create({
name: req.body.name,
text: req.body.text,
tutorialId: req.params.tutorialId,
})
.then( ... )
.catch( ... );
}
Then in Postman I receive a 500 (of the error message above) when issuing the request:
POST localhost:3000/api/tutorials/1/comments
{
"name": "John Doe",
"text": "Lorem ipsum..."
}
I don't think I should have to define a tutorialId field on the Comment model. Grr...
This may be very obvious to some of you, but it's tripping me up trying to learn. Any help is very much appreciated. :)
The issue that you're having is a result of using aliases via the as property. See the docs for belongsTo and hasMany. Here's a code sample that performs the inserts without the error.
let {
Sequelize,
DataTypes,
} = require('sequelize')
async function run () {
let sequelize = new Sequelize('dbname', 'username', 'password', {
host: 'localhost',
port: 5555,
dialect: 'postgres',
logging: console.log
})
let Comment = sequelize.define('comment', {
name: {
type: DataTypes.STRING,
},
text: {
type: DataTypes.STRING,
},
})
let Tutorial = sequelize.define('tutorial', {
title: {
type: DataTypes.STRING,
},
content: {
type: DataTypes.STRING,
}
})
Tutorial.hasMany(Comment)
Comment.belongsTo(Tutorial)
// This just recreates the tables in the database.
// You would really only want to use a force sync
// in a development environment, since it will destroy
// all of the data....
await sequelize.sync({ force: true })
let tutorial = await Tutorial.create({
title: 'Tutorial',
content: 'Hmm....'
})
let comment = await Comment.create({
name: 'Comment',
text: 'Something, something....',
tutorialId: tutorial.id,
})
await sequelize.close()
}
run()
Edit
This is just an edit to my original answer above. The OP Tom Doe discovered that the issue was being caused by a mismatch between the definitions of the tables in the database and the models defined via sequelize (see comments below). As we discovered, one way to troubleshoot the mismatch is to force sync a new version of the database, and then compare the new version of the database with the original version. There may be differences in the definitions of the columns or the contraints. Force syncing the database can be done via the command
await sequelize.sync({ force: true})
Important Note: The above statement will overwrite the existing database and all of its data. See the docs for more information.

'Table not found' error when inserting row. Sequelize and nodejs

When I'm trying to import user into database with User.create(), sequelize trows me error that says that table doesn't exist. Even tho I created a table line above the create function. My goal is to add user without using .then() function on .sync function.
I've tried to put sync function in await as I imagined that the sync function takes longer to finish.
// imports ...
// Connecting to database
// Creating ORM object
const db = new sequelize(format("%s://%s:%s#%s:%s/%s", gvars.db_soft, gvars.db_user, gvars.db_pass, gvars.db_host, gvars.db_port, gvars.db_daba));
db.authenticate().then(() => {
console.log("Connection established.");
}).catch(err => {
console.error(err);
});
// Define users table
const User = db.define("users", {
firstName: {
type: sequelize.STRING,
allowNull: false
},
lastName: {
type: sequelize.STRING,
allowNull: false
}}, { freezeTableName: true,
});
db.sync({ force: true }).then(() => { console.log("Table created."); });
User.create({
firstName: "Milan",
lastName: "Vjestica"
});
//...starting app
I expect for user to be added in table.
You have to use promise in sequelize as it is a promised based ORM,try following changes:
User.create({ firstName: "Milan",lastName: "Vjestica"}).then(function(user)
{
console.log(user.get('firstName'));
console.log(user.get('lastName'));
});

Express.js and MySQL model + validation

I am developing application using Node.js and Express framework. I found many examples of modeling data using MongoDB, but my project requires SQL database.
Could someone make simple explanation, what is the best way to make models based on MySQL?
Also I am wondering how to provide later validation of those models. Maybe I should define validation attributes inside each of them?
There is no best way to make models based on MySQL. You could implement your own way to handle models, but there are many ORM modules available for Node.js, I'd suggest using one of those.
I use Sequelize as ORM to define models and interact with the database in several Express applications. Another ORM for Node that I've run into is Bookshelf.js, but there are many others. Wich one to use depends on your preferences and necessities.
EDIT: Example of usage
I suggest the following structure when using Sequelize models: a directory in your project named models with a file for each model and an index.js file to load the Sequelize environment. If you use the Sequelize CLI, it also has several methods that follow this structure.
index.js
const fs = require("fs");
const path = require("path");
const Sequelize = require("sequelize");
let sqize = new Sequelize({
host : "1.2.3.4",
port : 1234,
database : "testDb",
username : "pino",
password : "th1S1s#c0mpL3xP4sSw0rD",
dialect: 'mysql',
});
fs.readdirSync(__dirname).filter(function(file) {
return (file.indexOf(".") !== 0) && (file !== "index.js");
}).forEach(function(file) {
let 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;
db.op = Sequelize.Op;
module.exports = {
sqize: sqize,
Sequelize: Sequelize,
op: Sequelize.Op
};
users.js
module.exports = function (sequelize, DataTypes) {
let users = sequelize.define('users', {
username: {
type: DataTypes.STRING(255),
allowNull: true
},
firstname: {
type: DataTypes.STRING(255),
allowNull: true
},
secondname: {
type: DataTypes.STRING(255),
allowNull: true
},
email: {
type: DataTypes.STRING(255),
allowNull: true
},
type: {
type: DataTypes.INTEGER(4),
allowNull: true,
references: {
model: 'users_type',
key: 'id'
}
},
password: {
type: DataTypes.STRING(255),
allowNull: true
},
salt: {
type: DataTypes.STRING(255),
allowNull: true
}
}, {
tableName: 'users'
});
users.associate = function (models) {
users.belongsTo(models.user_types, {
foreignKey: "type",
as: "userType"
});
users.hasMany(models.user_logs, {
foreignKey: "user_id",
as: "userLogs"
});
};
return users;
};
For more parameters and details, you can check the Sequelize doc, which is very simple and full of examples and details.
Also, I've used some ECMAScript 6, so change or transpile this code if your version of Node.js does not support them.

How to fetch all fields of table using sequelize in nodejs?

I want to fetch all fields without to write all fields name of table. How to use * to fetch all the fields from the table ?
This is UserController function to fetch all the rows with all fields of table.
user.findAll({
attributes: ['name','email','mobile','dob','address','image','is_active'],
where:{
is_active:'1',
name:{$like:'%%'}
},
limit:10
}).then(function(users,fields){
console.log(users);
res.send({error:false,message:'users list',data:users});
}).catch(function(err){
console.log('Oops! something went wrong, : ', err);
});
This is model code and define some property of model.
var sequalize = require('../../config/db_config');
const User = sequalize.define('user',{},{
timestamps: false,
paranoid: true,
underscored: true,
freezeTableName: true,
tableName: 'user',
createdAt:'created_on',
updatedAt:'updated_on'
});
User.sync({force:false}).then(() => {
console.log('Table is created!');
}).catch(err => {
console.log('An error occur when table is created!');
});
module.exports = User;
Please help me that how to fetch all fields with write to attribute in controller.
Simply ommit the attributes key in your query and all the fields will return.
user.findAll({
where:{
is_active:'1',
name:{$like:'%%'}
},
limit:10
}).then(function(users){
console.log(users);
res.send({error:false,message:'users list',data:users});
}).catch(function(err){
console.log('Oops! something went wrong, : ', err);
});
EDIT: In your model definition is best if you specify the fields your table has. Like so: http://docs.sequelizejs.com/manual/tutorial/models-definition.html
Otherwise you will have to specify the attributes key in every find operation.
#yBrodsky is right . Also you should make model like this.so that it can know the field to select when no attribute.
const User = sequalize.define('user',{},{
timestamps: false,
paranoid: true,
underscored: true,
freezeTableName: true,
tableName: 'user',
createdAt:'created_on',
updatedAt:'updated_on'
});
to this
var sequalize = require('../../config/db_config');
const User = sequalize.define('user',{
name: {type: Sequelize.STRING},
email: {type: Sequelize.STRING},
mobile: {type: Sequelize.INTEGER},
dob: {type: Sequelize.DATE}
address: {type: Sequelize.STRING},
image: {type: Sequelize.INTEGER},
is_active: {type: Sequelize.BOOLEAN }
},{
timestamps: false,
paranoid: true,
underscored: true,
freezeTableName: true,
tableName: 'user',
createdAt:'created_on',
updatedAt:'updated_on'
});
for dtatype see here
http://docs.sequelizejs.com/manual/tutorial/models-definition.html#data-types
Simply remove attributes from model , you will be able fetch all columns

Sails_mysql adapter

I want to know how we can create more than one tables in MySQL using Node.js through ORM adapters. I have created a table through model i.e. 'us.js'
module.exports = {
identity: 'us',
connection: 'mysqlDB',
schema:true,
migrate: 'safe',
attributes: {
as_a: 'string',
i_want_to: 'string',
for_the:'string',
so_that:'string'
}
};
And built its connection as connections.js:
var mysqlAdapter = require('sails-mysql');
var mongoAdapter = require('sails-mongo');
module.exports = {
adapters: {
mongoAdapt: mongoAdapter,
mysqlAdapt: mysqlAdapter
},
connections: {
mysqlDB: {
adapter: 'mysqlAdapt',
host: 'localhost',
database:'user_stories',
user:'root',
password:'',
supportBigNumbers:true, //true/false
debug:['ComQueryPacket'], //false or array of node-mysql debug
options
trace:true //true/false
}
}
};
So with the same connection how can I create more than one tables in MySQL database.
Create a new model for a new table. In the model, specify those attributes which you want as a fields in the table.