简体   繁体   English

从 NodeJS AWS Lambda 函数查询 MySQL 数据库

[英]Querying a MySQL database from a NodeJS AWS Lambda Function

I'm having a problem querying my MySQL database (hosted remotely from AWS) inside of my AWS Lambda function.我在 AWS Lambda 函数内部查询 MySQL 数据库(从 AWS 远程托管)时遇到问题。

This is my code except for the parts I need for the rest of Lambda function (which is being called for an Alexa Skill):这是我的代码,除了 Lambda 函数的其余部分(正在为 Alexa 技能调用)所需的部分:

  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 just fine when I run it with node from my command prompt:当我从命令提示符使用 node 运行它时,这很好用:

node index.js

I'm using the "mysql" module installed via npm in the directory with index.js and zip it and upload it to my Lambda function.我正在使用通过 npm 安装在 index.js 目录中的“mysql”模块,并将其压缩并上传到我的 Lambda 函数。

Again, this works on my development machine, but gives no indicator when testing my Lambda function as to why it doesn't effect my database at all.同样,这适用于我的开发机器,但在测试我的 Lambda 函数时没有给出任何指示,说明为什么它根本不影响我的数据库。

My question extends into Alexa and Lambda as much as it does the proper usage of the mysql Node.JS module.我的问题扩展到 Alexa 和 Lambda,就像它正确使用 mysql Node.JS 模块一样。

Here's my current code for my Lambda, and the problem here, of course, is still that my test value -> a username called "TESTNAME" doesn't get added to my MySQL database.这是我当前的 Lambda 代码,当然,这里的问题仍然是我的测试值 -> 名为“TESTNAME”的用户名没有添加到我的 MySQL 数据库中。

I put the query into the connect callback as the first comment suggests, and I'm putting my new code instead of updating my old code above just to keep a record of what how I think the code should transition to being in my Alexa's Lambda function:正如第一条评论所暗示的那样,我将查询放入连接回调中,并且我将我的新代码而不是更新我上面的旧代码只是为了记录我认为代码应该如何转换为我的 Alexa 的 Lambda 函数:

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  

The problem was that I needed to put my context.succeed inside of my callbacks.问题是我需要将我的 context.succeed 放在我的回调中。 Many thanks to sqlbot, as his talk of callbacks led me to study where things were actually ending their execution.非常感谢 sqlbot,因为他关于回调的谈话让我研究了事情实际上在哪里结束执行。

So apparently when using AWS Lambda, if the "context" ends before your callbacks get called, you don't get your callbacks.很明显,在使用 AWS Lambda 时,如果“上下文”在您的回调被调用之前结束,您将不会收到您的回调。 So even though I had placed all of my callbacks like so: connect -> query -> end, the first callback of the chain from connect never gets called because "context.succeed" was getting called right afterwards, which ended execution.因此,即使我像这样放置了所有回调:connect -> query -> end,来自 connect 的链的第一个回调从未被调用,因为“context.succeed”随后被调用,从而结束了执行。

Here's my code as of now (getting a proper query 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
    };
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM