My goal is to write the Fields from the JSON object below into a MySQL Database.
var dataRow = {
Table: "promosbudget",
Fields:[{
ManagerID: "Jose",
UserID: "ife",
Budget: "50000",
Year: "2015"
},
{
ManagerID: "Jose",
UserID: "fgs",
Budget: "50000",
Year: "2015"
},
{
ManagerID : "Jose",
UserID : "brz",
Budget : "50000",
Year : "2015"
}]
};
I'm using this command to receive and write the data:
app.post('/paramsjson', jsonParser, function(req, res) {
conMySQL.query('INSERT INTO ' + req.body.Table + ' SET ?',req.body.Fields,
function(err,result) {
console.log(result);
}
);
});
The issue is that I can only write the first JSON row, the other 2 rows are omitted.
I'd like to ask if there is a recommended method to do that right when I need to export a large JSON object (100.000 row), is it necessary to make a loop and read each row sequentially?
Thanks in advance for your help!
Try to go step by step.
Don't INSERT right into the database,
first console.log the outputs, look into the results, try to INSERT directly from the code. Then try to combine it all.
Anyway - I highly recommend using knex for any DB operation.
Take this sample codes for testing:
app.post('/paramsjson', jsonParser, function(req, res) {
console.log(req.body);
var table = req.body.Table;
var fields = req.body.Fields;
//If you want to use knex:
knex( table ).insert( fields )
.then(function (result) {
console.log(result)
})
.catch(function (err) {
console.log(err)
})
});
Related
I am developing a handlebars app,
router.get('/findBehavior/:student_id', async (req, res) => {
console.log("---> req.params.student_id :" + JSON.stringify(req.params.student_id));
const student = await Student.findByPk(req.params.student_id,{
include: Behavior,
});
console.log("---> student :" + JSON.stringify(student));
res.render('profile', {student, session: req.session});
});
but I have trouble reading this json data that comes into the profile.handlebars:
{
"student_id": 1,
"student_name": "Martina Hodson",
"student_grade": 9,
"Behaviors": [
{
"behavior_id": 1,
"behavior_name": "No Problems",
"StudentBehavior": {
"student_id": 1,
"behavior_id": 1
}
}
]
}
I am trying this code, but it is not working...
{{student.Behaviors.[0].['behavior_id']}}
I get a response of
[object SequelizeInstance:Behavior]
How can I get the student's name and the student's behaviors?
The problem was not the way I was trying to read the JSON.
It was that the object that comes in response of the search needs to be 'cleaned' before being passed to the handlebars page.
I used this code to make the object plain:
const student = dbStudentData.get({plain: true});
Yo can see how it appears surrounded by the rest of the code:
router.get('/findBehavior/:student_id', async (req, res) => {
console.log("---> req.params.student_id :" + JSON.stringify(req.params.student_id));
const dbStudentData = await Student.findByPk(req.params.student_id, {
include: Behavior,
});
// HERE --------------------------------------------------------
const student = dbStudentData.get({plain: true});
console.log("---> student :" + JSON.stringify(student));
res.render('profile', {student, session: req.session});
});
Since it was only one row of data, It wasn't needed a map function to make plain whole set of data when there is more than one row.
I have an array of objects which somewhat looks like this:
[
{
id: '5b29c08b-597c-460c-a3c7-ac8852b7a5dc',
option_text: 'njnj',
answer: false
},
{
id: '8ff5bda6-9335-495c-9c72-15ef258b899b',
option_text: 'jnjn',
answer: true
}
]
Here the answer column is inter-related like if any of the object's answer is set to true the other will come as false from frontend. So I've to update all the row associated with the referenced id.
What problem am facing is that the update query is not running but it is going inside the then block of the code instead of throwing error. Below is my code for the same:
// UPDATE Option
exports.updateOption = (req, res, next) => {
try {
console.log(req.body);
db.Option.update(req.body, {
where: { question_id: req.params.id }
}).then(() => {
console.log('A');
return res.status(200).send(errors.UPDATED_SUCESSFULLY);
}).catch(err => {
console.log('B');
return res.status(204).send(errors.INTERNAL_SERVER);
});
} catch(err) {
console.log('C');
return res.status(204).send(errors.INTERNAL_SERVER);
}
};
Sample Table Data for the same:
What I am thinking is that firstly to answer column false for all the rows associated with the same question_id and then update the particular row which has answer set to true.
But is this a good approach or anyone can suggest me some better solution ?
You should execute all updates in the same transaction (to avoid inconsistencies in DB):
sequelize.transaction(async transaction => {
const options = req.body;
for (const option of options) {
await db.Option.update(option, {
where: { question_id: req.params.id },
transaction
});
}
}).then(...
**How to Remove double quotes from my output **
app.get('/yearexpense',(req,res)=>{
mysqlConnection.query('SELECT login.display_name AS label, group_concat( daily_expenses.amount) AS data FROM login JOIN daily_expenses ON login.id = daily_expenses.user GROUP BY daily_expenses.user',(err,rows,fields)=>{
if(!err)
res.send(rows);
})
});
Expected Output
[
{ data: [330, 600], label: 'Ravi' },
{ data: [120, 455], label: 'Amit' },
{ data: [45, 67], label: 'Roshan' }
];
Getting Output
[{"label":"Ravi Kanti","data":"[314,444]"},{"label":"Amit prakash","data":"[78]"},{"label":"Roshan Kumar","data":"[215,80,165]"}]
The rows variable inside of your query() callback contains the expected results.
W3Schools has some examples:
https://www.w3schools.com/nodejs/nodejs_mysql_select.asp
The arrow function passed as parameter to mysqlConnection.query is a callback. That means you cannot know when it will be executed.
you can use async/await syntax to make your call block until the query gives you a result.
You may need to use util.promisify on mysqlConnection.query to make it return a Promise.
Try this instead:
app.get('/yearexpense', async (req,res) => {
try {
const results = await mysqlConnection.query('SELECT login.display_name AS label, group_concat( daily_expenses.amount) AS data FROM login JOIN daily_expenses ON login.id = daily_expenses.user GROUP BY daily_expenses.user')
// process the results
// res.send(results)
} catch(error) {
console.log(error)
// deal with the error
}
})
Remember: to use the keyword await the surrounding function must be marked as async
I am writing rest using node, sequelize as ORM for mySQL.
I am using bulkCreate function to create record in bulk. But in response it is returning null for primary key value.
Model
sequelize.define('category', {
cat_id:{
type:DataTypes.INTEGER,
field:'cat_id',
primaryKey: true,
autoIncrement: true,
unique:true
},
cat_name:{
type: DataTypes.STRING,
field: 'cat_name',
defaultValue:null
}
});
Bulk Create operation :
var data = [
{
'cat_name':'fashion'
},
{
'cat_name':'food'
}
];
orm.models.category.bulkCreate(data)
.then(function(response){
res.json(response);
})
.catch(function(error){
res.json(error);
})
response :
[
{
"cat_id": null,
"cat_name": "fashion",
"created_at": "2016-01-29T07:39:50.000Z",
"updated_at": "2016-01-29T07:39:50.000Z"
},
{
"cat_id": null,
"cat_name": "food",
"created_at": "2016-01-29T07:39:50.000Z",
"updated_at": "2016-01-29T07:39:50.000Z"
}
]
You should set the returning option:
Model.bulkCreate(values, {returning: true})
Tested in MySQL:
Model.bulkCreate(values, { individualHooks: true })
var data = [
{
'cat_name':'fashion'
},
{
'cat_name':'food'
}
];
Model.bulkCreate(data)
.then(function() {
//(if you try to immediately return the Model after bulkCreate, the ids may all show up as 'null')
return Model.findAll()
})
.then(function(response){
res.json(response);
})
.catch(function(error){
res.json(error);
})
The success handler is passed an array of instances, but please notice that these may not completely represent the state of the rows in the DB. This is because MySQL and SQLite do not make it easy to obtain back automatically generated IDs and other default values in a way that can be mapped to multiple records. To obtain Instances for the newly created values, you will need to query for them again.
http://docs.sequelizejs.com/en/latest/api/model/#bulkcreaterecords-options-promisearrayinstance
Unfortunately that doesn't work in the latest version. They explain why here:
http://sequelize.readthedocs.org/en/latest/api/model/#bulkcreaterecords-options-promisearrayinstance
note that the description specifically mentions mysql. You'll have to query for them. (example includes var _ = require('lodash');
var cat = rm.models.category;
cat.bulkCreate(data)
.then(function (instances) {
var names = _.map(instances, function (inst) {
return inst.cat_name;
});
return cat.findAll({where: {cat_name: {$in: names}});
})
.then(function(response){
res.json(response);
})
.catch(function(error){
res.json(error);
});
From the documentation: please notice that these may not completely represent the state of the rows in the DB. This is because MySQL and SQLite do not make it easy to obtain back automatically generated IDs and other default values in a way that can be mapped to multiple records. To obtain Instances for the newly created values, you will need to query for them again.
http://docs.sequelizejs.com/class/lib/model.js~Model.html#static-method-bulkCreate
But you can pass an option to make it return the id
orm.models.category.bulkCreate(data, { returning: true })
var data = [{
'cat_name':'fashion'
},
{
'cat_name':'food'
}
];
orm.models.category.bulkCreate(data,{individualHooks: true})
.then(function(response){
res.json(response);
})
.catch(function(error){
res.json(error);
});
I have a Sequelize object called Org which represents a row in the organisations table stored in MySQL. This table has a UUID primary key(id) stored as a 16 byte varbinary. If I have the UUID of an object (bfaf1440-3086-11e3-b965-22000af9141e) as a string in my JavaScript code, what is the right way to pass it as a parameter in the where clause in Sequelize?
Following are the options I've tried
Model: (for an existing MySQL table)
var uuid = require('node-uuid');
module.exports = function(sequelize, Sequelize) {
return sequelize.define('Org', {
id: {
type: Sequelize.BLOB, //changing this to Sequelize.UUID does not make any difference
primaryKey: true,
get: function() {
if (this.getDataValue('id')) {
return uuid.unparse(this.getDataValue('id'));
}
}
},
name: Sequelize.STRING,
}, {
tableName: 'organisation',
timestamps: false,
}
});
};
Option 1: Pass UUID as byte buffer using node-uuid
Org.find({
where: {
id: uuid.parse(orgId)
}
}).then(function(org) {
success(org);
}).catch(function(err) {
next(err);
});
Executing (default): SELECT `id`, `name` FROM `Organisation` AS `Org`
WHERE `Org`.`id` IN (191,175,20,64,48,134,17,227,185,101,34,0,10,249,20,30);
Sequelize treats the byte buffer as multiple values and so I get multiple matches and the top most record (not the one that has the right UUID) gets returned.
Option 2: Write a raw SQL query and pass the UUID as a HEX value
sequelize.query('SELECT * from organisation where id = x:id', Org, {plain: true}, {
id: orgId.replace(/-/g, '')
}).then(function(org) {
success(org);
}).catch(function(err) {
next(err);
});
Executing (default): SELECT * from organisation
where id = x'bfaf1440308611e3b96522000af9141e'
I get the correct record, but this approach is not really useful as I have more complex relationships in the DB and writing too many queries by hand beats the purpose of the ORM.
I'm using Sequelize 2.0.0-rc3.
Solved it by supplying a fixed size empty Buffer object to uuid.parse().
Got it working initially using ByteBuffer, but then realised that the same can be achieved using uuid.parse()
Org.find({
where: {
id: uuid.parse(orgId, new Buffer(16))
}
}).then(function(org) {
console.log('Something happened');
console.log(org);
}).catch(function(err) {
console.log(err);
});
Executing (default): SELECT `id`, `name` FROM `Organisation` AS `Org`
WHERE `Org`.`id`=X'bfaf1440308611e3b96522000af9141e';
If the accepted answer didn't work for you, here's what worked for me.
Note: My objective is to find an instance of an event based on a column which is not the primary key.
// guard clause
if (!uuid.validate(uuid_code))
return
const _event = await event.findOne({ where: { uuid_secret: uuid_code } })
// yet another guard clause
if (_event === null)
return
// your code here