JSON result is showing command of SUM MySQL - mysql

I'm getting an effective return calculation of all values column my MYSQL table but when i went to check my api result; the column value sum command is appearing in the result of the JSON.
[
{
"SUM(producFinalPrice)": 6000
}
]
This my router get data from my data base.
router.get('/sell/home-card-last-sell-compared-to-the-previous-day', function (req, res) {
connection.query('SELECT SUM(producFinalPrice) FROM new_sell',
function (err, lastSellComparedToThePreviousDayCardHome, fields) {
if (err) {
throw err;
}
res.send(lastSellComparedToThePreviousDayCardHome);
}
);
});
`
Making my mistake clearer, i'm making the final request from the previous query in AJAX; Through this way.
$(function () {
$.ajax({
type: "GET",
url: "/sell/home-card-last-sell-compared-to-the-previous-day",
success: function (lastSellComparedToThePreviousDayCardHome) {
var $lastSellComparedPreviousDay = $('#last-sell-compared-to-the-previous-day');
$.each(lastSellComparedToThePreviousDayCardHome, function (i, SellPreviousDay) {
$lastSellComparedPreviousDay.append('<li>R$ ' + SellPreviousDay.producFinalPrice + '.</li>');
});
console.log('Sucess return to Last Sell Previous Day!', lastSellComparedToThePreviousDayCardHome);
}
});
});
Basically that's it I could not find anything that would help me..
Thanks for helping me out ;]

Use an alias:
connection.query('SELECT SUM(producFinalPrice) AS productFinalSum FROM new_sell', ...
^^^^^^^^
Then when you parse your JSON in Node check for the productFinalSum key. Actually, I think you could even use SUM(productFinalSum) to access your JSON, but it looks awkward.

Related

How to get the answer of a mysql request and stock it?

I'm building a server and i'm trying to know if a key is in my sql DB.
I want to know if it is possible to get only the value of sql request or do I need to parse it?
function checkKey(key) {
var sqlcheck = "SELECT customerID from authentification where discord_key =
?";
console.log("in function");
DB.query(sqlcheck, [key], function (err, result) {
if (err) throw err;
console.log(result);
});
}
this is what I get :
RowDataPacket { customerID: 'cus_ET5gXP7p7Tafmf' }
but I am looking to get only:
cus_ET5gXP7p7Tafmf
Thank you for your help!
generally
result[0].customerID
however in your example it looks like
result.customerID

Why is my AWS Lambda node.js mysql query not returning?

I'm trying to write some external data into some local tables. We'll be looping through an array, writing most of the data in each array element to the main table and the rest to related tables, replacing all the data each time.
I've stripped the code down to the bare bones to show the problem I'm having. The DELETE runs fine, but the INSERT runs only once, and doesn't even return.
I have a screenshot of the output at https://imgur.com/a/zA6Hz8g .
In it, you can see that the code for the DELETE runs fine (ComQueryPacket sent, OkPacket returned) but when it gets to the INSERT, the ComQueryPacket is sent but nothing is returned. And then the code just falls through.
This results in the first row writing successfully, but no subsequent rows get written.
I've tried changing the connection to use pools, but that didn't help either.
Any ideas?
var mysql = require('mysql');
var promise = require('promise');
const con = mysql.createConnection({
<connectionInfo>,
debug: true
});
function connectToDB() {
return new promise((resolve, reject) => {
console.log("IN connectToDB");
con.connect(function(err) {
if (err) {
console.log("ERROR: Could not connect -- " + err);
reject;
}
console.log("Connected!");
resolve();
});
});
}
function deleteExistingMainRow() {
return new promise((resolve, reject) => {
var query = "DELETE FROM my_table";
con.query(query, [],
function(err, result) {
if (err) {
console.log("ERROR in deleteExistingMainRow: " + err);
reject;
}
else {
console.log("DEBUG: Successful delete of main row");
resolve();
}
});
});
}
function writeMainRow(data_row) {
return new promise((resolve, reject) => {
console.log("IN writeMainRow");
var query = 'INSERT INTO my_table SET id = ?';
con.query(query, [data_row.id],
function(err, result) {
console.log("YES we tried to query");
if (err) {
console.log("ERROR in writeMainRow: " + err);
reject(err);
}
else {
console.log("DEBUG: Successful write of main row");
resolve();
}
});
});
}
exports.handler = function(event, context) {
connectToDB().then(function(script) {
deleteExistingMainRow().then(function(script) {
var data = [{ "id": 1 }, { "id": 2 }, { "id": 3 }];
data.forEach(data_row => {
writeMainRow(data_row).then(function(script) {
console.log("DEBUG: Main row written in forEach");
},
function(err) {
if (err) { console.log("ERR"); } process.exit(0);
}());
});
console.log("DEBUG: Hey we're exiting now");
con.commit;
con.end(function(err) {
console.log("Error on con end: " + err);
});
context.done(null, "DONE");
process.exit(0);
});
});
};
Just a few moths ago AWS made Node.js v 8.10 runtime available in lambda.
Which means, you can use async/await and Promises. So, we can rearrange code to something like this:
exports.handler = async (event, context) => {
const dbConnection = await connectToDB();
await deleteExistingMainRow();
const data = [{ "id": 1 }, { "id": 2 }, { "id": 3 }];
// use here for...of loop to keep working with async/await behaviour
for(const data_row of data){
await writeMainRow(data_row);
}
}
Also, you can rewrite your code to use native Promises or async/await functions.
And of course, cover logic on try/catch block, I've skipped them for simplicity.
The reason why your code is not behaving as you expect is because of the asynchronous nature of NodeJS.
Your for_each loop spawns several threads that are going to INSERT the data in your database.
As soon as these threads are started, the rest of the code will execute, starting with console.log("DEBUG: Hey we're exiting now");
So the commit happens before all the INSERT calls are done and, more importantly, you're calling Process.exit() in your code. This terminates the runtime, even before the INSERT can finish.
Call callback() instead as per https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html
Handling your multiple asynchronous writes can be done differently. First, as grynets commented before me, I would strongly suggest to rewrite your code using async/await to make the call easier to read.
Then, you have to understand that each call to writeMainRow will return its own Promise and your code must wait for ALL promises to complete before to commit() and to callback()
Promise.all(...) will do that for you. See the doc at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
try using
INSERT INTO table_name(id) VALUES (?);
I know both your query and the above query works the same. Just give it a Try.
And just make sure your for loop is working properly sending values to the writeMainRow(function). It wouldnt show an error you if pass an empty value and make sure you are not passing the same values in the for loop. And i think you have to pass writeMainRow(data_row.id) rather than writeMainRow(data_row).
Hope this helps.
And one more suggestion if you are updating multiple rows there are options in mysql node library like transactions. Using those functions will be more effective and you can roll back the result if you face error. Other option is to write procedures, in which case you mysql server will bear the computation.

Knex creating database and inserting data to it

I am using Knex with node.js to create a table and insert some data to it. First I was first creating table and then inserting data but it ended up so that sometimes table was not created yet when data was going to be inserted. Then I ended up using callbacks like below. Now I'm mixing callbacks and promises and I'm not sure if it's very good thing. What could I do to make following work without callback and still take care that table is created before inserting data?
function executeCallback(next, tableName) {
knex.schema.hasTable(tableName)
.then((exists) => {
if (!exists) {
debug('not exists');
// Table creation for mysql
knex.raw(`CREATE TABLE ${tableName} ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, timestamp BIGINT NOT NULL, deviceId VARCHAR(255) NOT NULL, data JSON )`)
.then((rows) => {
debug(rows);
next('Table created (mysql)');
})
.catch((err) => {
debug(`Error: ${err}`);
next(`Error: ${err}`);
});
} else {
debug('Table exists');
next('Table exists');
}
});
}
.
executeCallback((response) => {
debug('back from callback', response);
debug('insert');
knex(req.body.tableName).insert({
timestamp: req.body.timestamp,
deviceId: req.body.deviceId,
data: req.body.data,
})
.catch((err) => {
debug(`Error: ${err}`);
res.status(500).json({ success: false, message: `Error: ${err}` });
})
.then((dataid) => {
debug(`Inserted with id: ${dataid}`);
res.status(201).json({ success: true });
});
}, req.body.tableName);
In general mixing callbacks and Promises is discouraged. I would suggest looking into the async/await pattern for using Promises, as that is often easier to read in code. It works well with knex js too.
One trick with Node callbacks is the convention of the function parameters, where the first parameter is the error, and the second is the success result. Like this: function (error, results) {...} This makes the result easy to check, like
if(error) {
// do error stuff
return
}
// do success stuff with `results`
One could call that function like next(new Error('bad')) for an error, or next(null, 'success object') for a success.
Your callback next is only taking one parameter, and you are not checking its value. It matters whether the result was 'Table Exists' 'Table Created' or 'Error' to what you do next.
You might try something like this:
async function handleInsert(tableName, res) {
try {
let hasTable = await knex.schema.hasTable(tableName)
if(!exists) {
let createResult = await knex.raw(`CREATE TABLE...`)
// check create results, throw if something went wrong
}
//table guaranteed to exist at this point
let insertResult = await knex(req.body.tableName).insert({
timestamp: req.body.timestamp,
deviceId: req.body.deviceId,
data: req.body.data,
})
debug(`Inserted with id: ${insertResult}`) //might need insertResult[0]
res.status(201).json({ success: true })
} catch(err) {
// any error thrown comes here
console.log('Server error: ' + err)
res.error('Bad thing happened, but do not tell client about your DB')
}
}
One more thing. In general, you can either assume the tables you need exist already. Or use a migration to build your DB on server start/update.

Node mysql bulk insert with express array parameter

I've come across a situation where I need to use a bulk insert with my Node project.
This of course has already been answered here: How do I do a bulk insert in mySQL using node.js
However, I have an express project which I use to create an api. The parameters are turned into an array and I'm having trouble using that array with a bulk insert. Whenever I try to use that route, I get an error of Error: ER_WRONG_VALUE_COUNT_ON_ROW: Column count doesn't match value count at row 1
After some digging I found that it tries to insert:
['foo', 'bar', 'test']
When I need it to insert:
['foo']
['bar']
['test']
Anyways, here's the whole code:
Route
router.post("/", function (req, res, next) {
db.query(
"REPLACE INTO user (`Name`) VALUES (?)",
[req.query.array],
function (error, response) {
if (error) throw error;
console.log(response);
}
)
});
Route Caller
let requestUrl = "http://localhost:3000/user?";
// External api request which returns a list of users
for (let i = 0; i < body.users.length; i++) {
requestUrl += `array=${body.users[i]}&`
}
let addUserRequest = {
url: requestUrl,
method: "POST"
};
request(addUserRequest, function (error, response, body) {
console.log(body);
});
The url that is generated is:
http://localhost:3000/user?array=foo&array=bar&array=test
Try this,
var datatoDB = [];
req.query.array.forEach(function(entry) {
console.log(entry);
datatoDB.push([entry]);
});
Here we are trying to convert this ['foo', 'bar', 'test'] to this [["foo"], ["bar"], ["test"]].
Now, use datatoDB in your function.
router.post("/", function (req, res, next) {
db.query(
"REPLACE INTO user (Name) VALUES ?",
[datatoDB],
function (error, response) {
if (error) throw error;
console.log(response);
}
)
});

how to import function value from var require?

I have this code:
server.js:
var sql = require('./libs/mysql');
app.get('/status', function(req, res) {
res.send(sql.readName('1600'));
});
mysql.js:
exports.readName = function(name){
var connection = mysql.createConnection(option);
connection.connect();
connection.query('SELECT id FROM asterisk.users WHERE name= '+name, function (err, rows, fields) {
console.log('mysql: ' +rows[0].id);
return(rows[0].id);
});
Now, when I send GET http://mydomain.com/status I can not receive responce. But in console log I see correct answer. Where is my error?
Most disk reading/DB access in node.js is done asynchronously. This allows node.js to be as fast as it claims. You need to use callback functions to handle the result of these read operations. If you are familiar with ajax, the concept is similar.
You are returning from connection.query which runs asynchronously. This is returned nowhere. readName actually returns nothing. What you need to do is actually pass in the callback that returns the value:
app.get("/status", function (req, res) {
sql.readName("1600", function (err, rows, fields) {
/* handle err */
res.send(rows[0].id);
});
});
This callback has to be called of course:
exports.readName = function (name, cb) {
/* snip */
connection.query(query + name, cb);
});
You can't get the result because the return statement is in the function function (err, rows, fields). You can use callback like this
var sql = require('./libs/mysql');
app.get('/status', function(req, res) {
sql.readName('1600', function(result){
res.send(result);
});
});
exports.readName = function(name, callback){
var connection = mysql.createConnection(option);
connection.connect();
connection.query('SELECT id FROM asterisk.users WHERE name= '+name,
function (err, rows, fields) {
console.log('mysql: ' +rows[0].id);
callback(rows[0].id);
});
}
Thanks for helping. I find http error causes described upper. Error appear if I use callback functions like this callback(row[0].id), but if we use syntax like this callback('id: '+row[0].id) everything it's ok. So when we send res.send(response) we cant send unnamed data, need to put there some descriptions.
So, my final code look like this:
server.js
var sql = require(./mysql);
app.get('/status', function(req, res) {
sql.readName('1600', function(result){
res.send(result);
});
});
mysql.js
var mysql=require(mysql);
exports.readName = function(name, callback){
var connection = mysql.createConnection(option);
connection.connect();
connection.query('SELECT id FROM asterisk.users WHERE name= '+name,
function (err, rows, fields) {
if(err) callback(err);
else{
console.log(rows[0].id);
callback('ID: '+rows[0].id);
}
});
return true;
};