Related
Currently I want to access MySQL Aurora DB from inside a lambda function.
I have both the Aurora and the lambda in same VPC, subnets and security group.
The following is the lambda function code:
console.log("Welcome to lambda")
var connection = mysql.createConnection({
host: 'aurora-test1-us-mysql-multilevel.cluster-cutke7yxox3c.us-west-2.rds.amazonaws.com',
database: 'aurora-test1-us-mysql-multilevel',
user: "***",
password: "***",
});
console.log("createConnection",connection)
let con = connection.connect();
console.log("connect:",con)
const query = connection.query('USE feature;SELECT * FROM feature;')
console.log("query",query)
connection.end();
return {
statusCode: 200,
body: "HELLO KIMOO!!! Welcome TO AURORA DB" + "Database Created2"
}
}
catch(err)
{
console.log("Error caught",err)
return {
statusCode: 500,
body: JSON.stringify({
message: 'Error: ' + err
})
}
}
The following is the output received from logging the query
_events: [Object: null prototype] {
error: [Function (anonymous)],
packet: [Function (anonymous)],
timeout: [Function (anonymous)],
end: [Function (anonymous)]
},
_eventsCount: 4,
_maxListeners: undefined,
_callback: undefined,
_callSite: Error
at Protocol._enqueue (/var/task/node_modules/mysql/lib/protocol/Protocol.js:144:48)
at Connection.query (/var/task/node_modules/mysql/lib/Connection.js:198:25)
at Runtime.<anonymous> (/var/task/index.js:39:38)
at Generator.next (<anonymous>)
at /var/task/index.js:8:71
at new Promise (<anonymous>)
at __awaiter (/var/task/index.js:4:12)
at Runtime.handler (/var/task/index.js:17:12)
at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1089:29),
_ended: false,
_timeout: undefined,
_timer: Timer { _object: [Circular *1], _timeout: null },
sql: 'USE feature;SELECT * FROM feature;',
values: undefined,
typeCast: true,
nestTables: false,
_resultSet: null,
_results: [],
_fields: [],
_index: 0,
_loadError: null,
_connection: <ref *2> Connection {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
config: ConnectionConfig {
host: 'aurora-test1-us-mysql-multilevel.cluster-cutke7yxox3c.us-west-2.rds.amazonaws.com',
port: 3306, ......
I don't understand what does this error mean and how can I connect to Aurora and retrieve data from it successfully
Note:
I'm using Typescript
I'm using mysql library
I am working in express and Node-js and I am working in MySql in Node. I want to store the user data in the database but checking whether the user is already present or not. the working is that on the starting of the function it call the userpresent function to check that the is present or not. I want to return the true or false but I is returning an object and I cannot handle it the code is what I do in this code to use the return value(which must be true or false) in route function:
const express = require('express');
const router = express.Router();
const database = require('../DBconfig');
var mysql = require('mysql');
const { body, validationResult } = require('express-validator');
// to make connection with the database
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'yourguide',
});
// connection statement is end
//the route function is start
// here I added some express validators
router.post(
'/signup',
[
body('username', 'enter username of min 4 character').isLength({ min: 3 }),
body('firstName', 'enter firstName of min 3 character').isLength({
min: 3,
}),
body('lastName', 'enter lastname of min 3 character').isLength({ min: 3 }),
body('password', 'enter password of min 4 character').isLength({ min: 4 }),
body('city', 'enter city of min 4 character').isLength({ min: 4 }),
body('email', 'entera valid email').isEmail(),
],
async (req, res) => {
const error = validationResult(req);
//check that the user enter a valid input
var flag = await userPresent(req.body.username, req.body.email);
if (!error.isEmpty()) {
return res.status(400).json({ error: error.array() });
} else {
// if the input is valid then start to check the user
await connection.connect(function (err) {
if (err) console.log('not conntected to table');
else console.log('connected to table');
// call the async function to check the presence of the user
console.log('flag in main is ');
console.log(flag);
//check the return value of the fucntion
//if the user is not present then execute the if statement
if (!flag) {
//make the query
var query = `INSERT INTO users(firstName, lastName, username, email, city, password) VALUES ("${req.body.firstName}","${req.body.lastName}","${req.body.username}","${req.body.email}","${req.body.city}","${req.body.password}")`;
console.log(query);
connection.query(query, function (err, result) {
if (err) {
flag = false;
console.log('not inserted');
return flag;
} else {
flag = true;
console.log('inserted');
return flag;
}
});
return res.body;
} else {
return res
.status(400)
.json({ error: 'given email or username is already exist' });
}
});
}
}
);
//async function to check the user presence
userPresent = async (username, email) => {
//initialize the flag with true
let data = '';
//make query to check the user
var query = `SELECT * FROM users WHERE username= "${username}" AND email="${email}" `;
data = await connection.query(
query,
(present = (err, result) => {
return result != null;
})
);
console.log('data is ', data);
};
the userpresent function return the object
_events: [Object: null prototype] {
error: [Function (anonymous)],
packet: [Function (anonymous)],
timeout: [Function (anonymous)],
end: [Function (anonymous)]
},
_eventsCount: 4,
_maxListeners: undefined,
_callback: [Function (anonymous)],
_callSite: Error
at Protocol._enqueue (D:\practise\yourguide\yourguide\backend\node_modules\mysql\lib\protocol\Protocol.js:144:48)
at Connection.query (D:\practise\yourguide\yourguide\backend\node_modules\mysql\lib\Connection.js:198:25)
at userPresent (D:\practise\yourguide\yourguide\backend\routes\user.js:83:29)
at D:\practise\yourguide\yourguide\backend\routes\user.js:28:22
at Layer.handle [as handle_request] (D:\practise\yourguide\yourguide\node_modules\express\lib\router\layer.js:95:5)
at next (D:\practise\yourguide\yourguide\node_modules\express\lib\router\route.js:137:13)
at middleware (D:\practise\yourguide\yourguide\backend\node_modules\express-validator\src\middlewares\check.js:16:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5),
_ended: false,
_timeout: undefined,
_timer: Timer { _object: [Circular *1], _timeout: null },
sql: 'SELECT * FROM users WHERE username= "harry13" AND email="harry13#gmail.com" ',
values: undefined,
typeCast: true,
nestTables: false,
_resultSet: null,
_results: [],
_fields: [],
_index: 0,
_loadError: null,
_connection: <ref *2> Connection {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
config: ConnectionConfig {
host: 'localhost',
port: 3306,
localAddress: undefined,
socketPath: undefined,
user: 'root',
password: 'root',
database: 'yourguide',
connectTimeout: 10000,
insecureAuth: false,
supportBigNumbers: false,
bigNumberStrings: false,
dateStrings: false,
debug: undefined,
trace: true,
stringifyObjects: false,
timezone: 'local',
flags: '',
queryFormat: undefined,
pool: undefined,
ssl: false,
localInfile: true,
multipleStatements: false,
typeCast: true,
maxPacketSize: 0,
charsetNumber: 33,
clientFlags: 455631
},
_socket: Socket {
connecting: true,
_hadError: false,
_parent: null,
_host: 'localhost',
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 5,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
timeout: 10000,
[Symbol(async_id_symbol)]: 36,
[Symbol(kHandle)]: [TCP],
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: Timeout {
_idleTimeout: 10000,
_idlePrev: [TimersList],
_idleNext: [TimersList],
_idleStart: 3579,
_onTimeout: [Function: bound ],
_timerArgs: undefined,
_repeat: null,
_destroyed: false,
[Symbol(refed)]: false,
[Symbol(kHasPrimitive)]: false,
[Symbol(asyncId)]: 39,
[Symbol(triggerId)]: 0
},
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0
},
_protocol: Protocol {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
readable: true,
writable: true,
_config: [ConnectionConfig],
_connection: [Circular *2],
_callback: null,
_fatalError: null,
_quitSequence: null,
_handshake: true,
_handshaked: false,
_ended: false,
_destroyed: false,
_queue: [Array],
_handshakeInitializationPacket: null,
_parser: [Parser],
[Symbol(kCapture)]: false
},
_connectCalled: true,
state: 'disconnected',
threadId: null,
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false
}
what I do to return the true or false to use in our route function
I'm trying to understand how to use the node js util to promisify pool connections.
I would keep my code clean using async/await logic ( without the callback hell, that I really don't like especially with transactions ).
here is my config file:
const mysql = require('mysql');
const util = require('util');
const pool = mysql.createPool({
connectionLimit: 10,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
});
// Ping database to check for common exception errors.
pool.getConnection((err, connection) => {
if (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
console.error('Database connection was closed.')
}
if (err.code === 'ER_CON_COUNT_ERROR') {
console.error('Database has too many connections.')
}
if (err.code === 'ECONNREFUSED') {
console.error('Database connection was refused.')
}
}
if (connection) connection.release();
return;
})
// Promisify for Node.js async/await.
pool.query = util.promisify(pool.query)
module.exports = pool;
I'm executing single easy queries like this (and they work fine):
let sql = "SELECT * FROM products WHERE code = ? ;"
let param = [code];
let results = await pool.query(sql, param);
I'm developing transactions in this way ( I think it is a completely wrong approach ):
try {
await pool.query('START TRANSACTION');
sql = "INSERT INTO test (name) VALUES ( ? ) ;"
param = ['pippo'];
results = []
await pool.query(sql, param);
await pool.query('COMMIT');
} catch (error) {
await pool.query('ROLLBACK');
return next(error)
}
With transactions I shouldn't use pool.query ( that, I think, get each time a new connection and automatically release it when the query is finished ).
It seems to me that pool.query create a big problem with transactions:
If just run one transaction at a time is ok, but if run 2 (or more) transactions at the same time maybe the COMMIT of the second transaction can COMMIT all the queries of the first transaction just because is executed before the first COMMIT.
I think I should instead get a new connection use the connection for the entire flow of the transaction and release it at the end. So each transaction flow needs an own connection.
But I don't know how to promisify a pool.getConnection as I promisify the pool.query.
I was trying something like:
pool.getConnection = util.promisify(pool.getConnection).bind(pool)
const conn = await pool.getConnection();
let sql = "SELECT * FROM test ;"
let param = [];
let results = await conn.query(sql); // I don't get here the expected rows
but it doesn't work. I don't become the rows in result but if i console.log(results) I have this:
Query {
_events: [Object: null prototype] {
error: [Function],
packet: [Function],
timeout: [Function],
end: [Function]
},
_eventsCount: 4,
_maxListeners: undefined,
_callback: undefined,
_callSite: Error
at Protocol._enqueue (C:\Users\rocco\wa\ferramenta\server\node_modules\mysql\lib\protocol\Protocol.js:144:48)
at PoolConnection.query (C:\Users\rocco\wa\ferramenta\server\node_modules\mysql\lib\Connection.js:198:25)
at C:\Users\rocco\wa\ferramenta\server\routes\imports.js:304:30
at processTicksAndRejections (internal/process/task_queues.js:97:5),
_ended: false,
_timeout: undefined,
_timer: Timer { _object: [Circular], _timeout: null },
sql: 'SELECT * FROM test ; ',
values: [],
typeCast: true,
nestTables: false,
_resultSet: null,
_results: [],
_fields: [],
_index: 0,
_loadError: null,
_connection: PoolConnection {
_events: [Object: null prototype] {
end: [Function: _removeFromPool],
error: [Function]
},
_eventsCount: 2,
_maxListeners: undefined,
config: ConnectionConfig {
host: 'localhost',
port: '3306',
localAddress: undefined,
socketPath: undefined,
user: 'root',
password: '---myPassword---',
database: '---nameOfMyDb---',
connectTimeout: 10000,
insecureAuth: false,
supportBigNumbers: false,
bigNumberStrings: false,
dateStrings: false,
debug: undefined,
trace: true,
stringifyObjects: false,
timezone: 'local',
flags: '',
queryFormat: undefined,
pool: [Pool],
ssl: false,
localInfile: true,
multipleStatements: false,
typeCast: true,
maxPacketSize: 0,
charsetNumber: 33,
clientFlags: 455631,
protocol41: true
},
_socket: Socket {
connecting: false,
_hadError: false,
_parent: null,
_host: 'localhost',
_readableState: [ReadableState],
readable: true,
_events: [Object: null prototype],
_eventsCount: 4,
_maxListeners: undefined,
_writableState: [WritableState],
writable: true,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
timeout: 0,
[Symbol(asyncId)]: 11,
[Symbol(kHandle)]: [TCP],
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: Timeout {
_idleTimeout: -1,
_idlePrev: null,
_idleNext: null,
_idleStart: 1284,
_onTimeout: null,
_timerArgs: undefined,
_repeat: null,
_destroyed: true,
[Symbol(refed)]: false,
[Symbol(kHasPrimitive)]: false,
[Symbol(asyncId)]: 14,
[Symbol(triggerId)]: 1
},
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0
},
_protocol: Protocol {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
readable: true,
writable: true,
_config: [ConnectionConfig],
_connection: [Circular],
_callback: null,
_fatalError: null,
_quitSequence: null,
_handshake: true,
_handshaked: true,
_ended: false,
_destroyed: false,
_queue: [Array],
_handshakeInitializationPacket: [HandshakeInitializationPacket],
_parser: [Parser],
[Symbol(kCapture)]: false
},
_connectCalled: true,
state: 'authenticated',
threadId: 117,
_pool: Pool {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
config: [PoolConfig],
_acquiringConnections: [],
_allConnections: [Array],
_freeConnections: [],
_connectionQueue: [],
_closed: false,
query: [Function],
getConnection: [Function: bound ],
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false
}
Some ideas ?
THX
Here is an easy example about how I solved it:
pool.getConnection = util.promisify(pool.getConnection)
let conn = await pool.getConnection();
conn.query = util.promisify(conn.query)
sql = "INSERT INTO test (name) VALUES ( ? ) ; ";
param = ['fakename'];
results = [];
results = await conn.query(sql, param)
conn.release(); // is important remember to release the connection
I'm new in node.js. I using AWS with node.js and MySQL to create a lambda function, but I can't catch the results in my handler, my database instance it's in RDS service.
When I launch my callback in the console it shows me a giant and unreadable json with information from the database but not from the records that I am consulting, why is this? because it happens, am I doing something wrong?
This is my code:
'use strict';
const AWS = require("aws-sdk");
AWS.config.update( { region: "us-west-2" } );
var mysql = require('mysql');
var querystring = require('querystring');
const con = mysql.createConnection({
host : process.env.RDS_HOSTNAME,
user : process.env.RDS_USERNAME,
password : process.env.RDS_PASSWORD,
database : process.env.RDS_DB_NAME
});
exports.handler = async (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
const results = await con.query('SELECT * FROM `documentoApp_rptenviadoclon`;');
await con.end();
if (results) {
callback(null, {
statusCode: 200,
headers: {
'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Requested-With',
'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(results)
});
} else {
callback('error', {
statusCode: 400,
headers: {
'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Requested-With',
'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',
'Access-Control-Allow-Origin': '*'
},
body: {
message: 'No results found.'
},
});
}
};
I tried to put a console.log in response body and this is what it shows, the giant and illegible json of which I speak:
START RequestId: 80dfacdb-034b-41bc-8c53-e5eb3347d035 Version: $LATEST
2020-03-20T21:57:15.134Z 80dfacdb-034b-41bc-8c53-e5eb3347d035 INFO Query {
_events: [Object: null prototype] {
error: [Function],
packet: [Function],
timeout: [Function],
end: [Function]
},
_eventsCount: 4,
_maxListeners: undefined,
_callback: undefined,
_callSite: Error
at Protocol._enqueue (/var/task/node_modules/mysql/lib/protocol/Protocol.js:144:48)
at Connection.query (/var/task/node_modules/mysql/lib/Connection.js:198:25)
at Runtime.exports.handler (/var/task/index.js:19:31)
at Runtime.handleOnce (/var/runtime/Runtime.js:66:25),
_ended: false,
_timeout: undefined,
_timer: Timer { _object: [Circular], _timeout: null },
sql: 'SELECT * FROM `documentoApp_rptenviadoclon`;',
values: undefined,
typeCast: true,
nestTables: false,
_resultSet: null,
_results: [],
_fields: [],
_index: 0,
_loadError: null,
_connection: Connection {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
config: ConnectionConfig {
host: '--hidden--',
port: 3306,
localAddress: undefined,
socketPath: undefined,
user: '--hidden--',
password: '--hidden--',
database: '--hidden--',
connectTimeout: 10000,
insecureAuth: false,
supportBigNumbers: false,
bigNumberStrings: false,
dateStrings: false,
debug: undefined,
trace: true,
stringifyObjects: false,
timezone: 'local',
flags: '',
queryFormat: undefined,
pool: undefined,
ssl: false,
localInfile: true,
multipleStatements: false,
typeCast: true,
maxPacketSize: 0,
charsetNumber: 33,
clientFlags: 455631
},
_socket: Socket {
connecting: true,
_hadError: false,
_parent: null,
_host: 'dbportalreportes-dev.cjawt1xkypqu.us-west-2.rds.amazonaws.com',
_readableState: [ReadableState],
readable: false,
_events: [Object: null prototype],
_eventsCount: 5,
_maxListeners: undefined,
_writableState: [WritableState],
writable: true,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
timeout: 10000,
[Symbol(asyncId)]: 3,
[Symbol(kHandle)]: [TCP],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: Timeout {
_idleTimeout: 10000,
_idlePrev: [TimersList],
_idleNext: [TimersList],
_idleStart: 469,
_onTimeout: [Function: bound ],
_timerArgs: undefined,
_repeat: null,
_destroyed: false,
[Symbol(refed)]: false,
[Symbol(asyncId)]: 7,
[Symbol(triggerId)]: 0
},
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0
},
_protocol: Protocol {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
readable: true,
writable: true,
_config: [ConnectionConfig],
_connection: [Circular],
_callback: null,
_fatalError: null,
_quitSequence: [Quit],
_handshake: true,
_handshaked: false,
_ended: false,
_destroyed: false,
_queue: [Array],
_handshakeInitializationPacket: null,
_parser: [Parser]
},
_connectCalled: true,
state: 'disconnected',
threadId: null
}
}
END RequestId: 80dfacdb-034b-41bc-8c53-e5eb3347d035
REPORT RequestId: 80dfacdb-034b-41bc-8c53-e5eb3347d035 Duration: 208.98 ms Billed Duration: 300 ms Memory Size: 128 MB Max Memory Used: 92 MB Init Duration: 415.02 ms
I hope you can help me, thank you very much!
I get below query result from postgreSQL data base, then I want to send the response which should only has part: rows to the client. I need the response is in json format, so could you please tell how can I convert the query result: rows into json array?
Result {
command: 'SELECT',
rowCount: 1,
oid: NaN,
rows:
[ anonymous {
uid: 23,
name: 'Test Human',
email: 'test#example.com',
password: 'test',
created: 2018-08-24T09:44:19.659Z,
terminited: null }
anonymous {
uid: 12,
name: 'Test Animal',
email: 'ani#example.com',
password: 'hello',
created: 2018-08-24T09:44:19.659Z,
terminited: null }
],
fields:
...
_parsers:
[ [Function: parseInteger],
[Function: noParse],
[Function: noParse],
[Function: noParse],
[Function: parseDate],
[Function: parseDate] ],
RowCtor: [Function: anonymous],
rowAsArray: false,
_getTypeParser: [Function: bound ] }
Node.js code:
// router for get friends information
router.get("/getfriends", (req, res) => {
const uid = req.query.uid;
pool.connect((err, client, done) => {
if (err) throw err;
const fetchRow = async() =>{
await client.query('SELECT * FROM friends where follower = $1 ORDER by id ASC', [uid], (err, result) => {
done()
if(err){
console.log(err.stack)
res.status(400).json(err)
} else {
/*here I want to response rows only with JSON format, but result.rows doesn't realise that...*/
console.log(result.rows)
res.status(200).json(result.rows)
}
})
}
fetchRow()
})
})