web-dev-qa-db-ja.com

NodeJS AWS Lambda関数からのMySQLデータベースのクエリ

AWS Lambda関数内でMySQLデータベース(AWSからリモートでホストされている)のクエリで問題が発生しています。

これは、残りの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();

これは、コマンドプロンプトからノードで実行すると問題なく機能します。

node index.js

私はindex.jsのあるディレクトリにnpm経由でインストールされた「mysql」モジュールを使用し、それをZip圧縮して、それをLambda関数にアップロードします。

繰り返しますが、これは開発マシンで機能しますが、Lambda関数をテストするときに、データベースにまったく影響を与えない理由を示すものはありません。

私の質問は、MySQL Node.JSモジュールを適切に使用するのと同じくらい、AlexaとLambdaにも及んでいます。

これが私のLambdaの現在のコードです。もちろん、ここでの問題は、テスト値->「TESTNAME」というユーザー名がMySQLデータベースに追加されないことです。

最初のコメントが示唆しているように、クエリを接続コールバックに入れ、コードをAlexaのLambda関数に移行する方法を記録するために、古いコードを更新する代わりに新しいコードを入れています:

更新されたコード:

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
    };
};

そして私のコンソール出力:

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  
9
Paul McElroy

問題は、コールバック内にcontext.succeedを配置する必要があることでした。 sqlbotに感謝します。コールバックについての彼の話から、実際にどこで実行が終了しているかを調べることができました。

したがって、AWS Lambdaを使用しているときに、コールバックが呼び出される前に「コンテキスト」が終了すると、コールバックが取得されません。したがって、すべてのコールバックを次のように配置したとしても、connect-> query-> endのように、connectからのチェーンの最初のコールバックは呼び出されません。

これが今のところ私のコードです(適切なクエリが今起こっています):

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
    };
};
5
Paul McElroy