Query a MySQL database using the NodeJS AWS Lambda function

I had a problem querying my MySQL database (hosted remotely from AWS) inside my AWS Lambda function.

This is my code, with the exception of the parts that I need for the rest of the lambda function (which is called for the Alexa skill):

var mysql = require('mysql'); var connection = mysql.createConnection({ host : '<myserver>', user : '<myusername>', password : '<mypw>', database : '<mydatabase>' }); connection.connect(function(err){ if(!err) { console.log("Database is connected ... nn"); } else { console.log("Error connecting database ... nn"); } }); connection.query("INSERT INTO Users (user_id) VALUES ('TESTNAME')"); connection.end(); 

This works fine when I run it using node from my command line:

 node index.js 

I use the mysql module installed via npm in the directory with index.js and zip it and load it into my Lambda function.

Again, this works on my development machine, but does not give an indicator when testing my Lambda function as to why it does not affect my database at all.

My question applies to Alexa and Lambda as well as to the proper use of the mysql Node.JS module.

Here is my current code for my Lambda, and the problem here, of course, still is that my test value -> username called "TESTNAME" is not added to my MySQL database.

I put the request in the connect callback as the first comment suggests, and I put my new code instead of updating my old code above to keep a record of how I think the code should go to being in my Alexa Lambda Function :

Updated code:

 var mysql = require('mysql'); var connection = mysql.createConnection({ host : '<myserver>', user : '<myusername>', password : '<mypw>', database : '<mydatabase>' }); exports.handler = (event, context) => { try { if (event.session.new) { // New Session console.log("NEW SESSION"); } switch (event.request.type) { case "LaunchRequest": // Launch Request console.log(`LAUNCH REQUEST`); context.succeed( generateResponse({}, buildSpeechletResponse("Welcome to an Alexa Skill, this is running on a deployed lamda function", true) ) ); break; case "IntentRequest": // Intent Request console.log(`Intent Request`); console.log('Then run MySQL code:'); connection.connect(function(err) { console.log('Inside connection.connect() callback'); if (!err) { console.log("Database is connected ... "); connection.query("INSERT INTO Users (user_id) VALUES ('TESTNAME')", function(err, result) { console.log("Inside connection.query() callback") if (!err) { console.log("Query Successful! Ending Connectection."); connection.end(); } else { console.log("Query error!"); } }); } else { console.log("Error connecting database ..." + err.message); } }); context.succeed( generateResponse({}, buildSpeechletResponse("Welcome to the incredible intelligent MySQLable Alexa!", true) ) ); break; case "SessionEndedRequest": // Session Ended Request console.log(`SESSION ENDED REQUEST`); break; default: context.fail(`INVALID REQUEST TYPE: ${event.request.type}`); } } catch (error) { context.fail(`Exceptiodn: ${error}`) } }; //Helpers buildSpeechletResponse = (outputText, shouldEndSession) => { return { outputSpeech: { type: "PlainText", text: outputText }, shouldEndSession: shouldEndSession }; }; generateResponse = (sessionAttributes, speechletResponse) => { return { version: "1.0", sessionAttributes: sessionAttributes, response: speechletResponse }; }; 

And my console output:

 START RequestId: 5d4d17a7-0272-11e7-951c-b3d6944457e1 Version: $LATEST 2017-03-06T13:39:47.561Z 5d4d17a7-0272-11e7-951c-b3d6944457e1 Intent Request 2017-03-06T13:39:47.562Z 5d4d17a7-0272-11e7-951c-b3d6944457e1 Then run MySQL code: END RequestId: 5d4d17a7-0272-11e7-951c-b3d6944457e1 REPORT RequestId: 5d4d17a7-0272-11e7-951c-b3d6944457e1 Duration: 82.48 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 14 MB 
+6
source share
1 answer

The problem was that I needed to put my context. Get access to my callbacks. Many thanks to sqlbot, as his talk about callbacks led me to learn where their execution actually ends.

Thus, it is obvious that when using AWS Lambda, if the "context" ends before the called calls are called, you are not getting your callbacks. Therefore, although I put all my callbacks like this: connect β†’ query β†’ end, the first chain callback from connect is never called because "context.succeed" was called immediately, which ended the execution.

Here is my code at the moment (getting the correct request is happening now):

 var mysql = require('mysql'); var connection = mysql.createConnection({ ... }); exports.handler = (event, context) => { try { if (event.session.new) { // New Session console.log("NEW SESSION"); } switch (event.request.type) { case "LaunchRequest": // Launch Request console.log(`LAUNCH REQUEST`); context.succeed( generateResponse({}, buildSpeechletResponse("Welcome to an Alexa Skill, this is running on a deployed lamda function", true) ) ); break; case "IntentRequest": // Intent Request console.log(`Intent Request`); console.log('Then run MySQL code:'); connection.connect(function(err) { console.log('Inside connection.connect() callback'); if (!err) { console.log("Database is connected ... "); connection.query("INSERT INTO Users (user_id) VALUES ('TESTNAME')", function(err, result) { console.log("Inside connection.query() callback") if (!err) { console.log("Query Successful! Ending Connection."); connection.end(); } else { console.log("Query error!"); } }); } else { console.log("Error connecting database ..." + err.message); } context.succeed( generateResponse({}, buildSpeechletResponse("Welcome to the incredible intelligent MySQLable Alexa!", true) ) ); }); break; case "SessionEndedRequest": // Session Ended Request console.log(`SESSION ENDED REQUEST`); break; default: context.fail(`INVALID REQUEST TYPE: ${event.request.type}`); } } catch (error) { context.fail(`Exceptiodn: ${error}`) } }; //Helpers buildSpeechletResponse = (outputText, shouldEndSession) => { return { outputSpeech: { type: "PlainText", text: outputText }, shouldEndSession: shouldEndSession }; }; generateResponse = (sessionAttributes, speechletResponse) => { return { version: "1.0", sessionAttributes: sessionAttributes, response: speechletResponse }; }; 
+3
source

Source: https://habr.com/ru/post/1015464/


All Articles