2017-03-04 8 views
6

AWSラムダ関数内でMySQLデータベース(AWSからリモートでホストされている)を照会する際に問題があります。NodeJS AWSラムダ関数からMySQLデータベースを照会

これは私が(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の」モジュールを使用して、それを圧縮し、私のラムダ関数にアップロードしています。

これも私の開発マシンでは動作しますが、私のラムダ関数をテストしてもデータベースがまったく効果を発揮しない理由はわかりません。

私の質問は、mysql Node.JSモジュールの適切な使い方と同じくらい、AlexaとLambdaにも広がっています。

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

最初のコメントが示唆しているように、私はこの問い合わせをconnectコールバックに入れました。私は古いコードを更新するのではなく、新しいコードを置いています。私のアレクサのラムダ関数:

更新コード:

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 
+0

あなたが接続コールバック内でクエリを実行する必要があります。ここで 'connect()'は何らかの形で同期しているかのように扱っているので、 'connect()'は 'query()'を実行したときに接続されているかもしれません。また、 'query()'のエラーを無視しているかもしれません。 –

+0

コールバック内の接続も終了する必要がありますか? –

+0

私は自分の質問の全面的な範囲に関するより多くの情報で質問を更新し、私の質問を自分のコールバックに入れることによってあなたが意味すると思ったことを追加しました。ラムダ関数のテスト時にコンソール出力が得られないので、MySQLデータベースにポストするとすぐに関数のエラー処理を行います。この時点では少し役に立たない。 –

答えて

3

問題は、私は私の詐欺を置くために必要なことでした私のコールバックの中のtext.succeed。 sqlbotのおかげで多くのことがありました。彼のコールバックの話は、実際に実行が終了した場所を勉強してくれました。

AWSラムダを使用しているときに、コールバックが呼び出される前に「コンテキスト」が終了した場合は、コールバックを取得できません。したがって、私はすべてのコールバックをconnect:> query-> endのように配置していたにもかかわらず、 "context.succeed"が後に呼び出されて実行を終了したため、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 
    }; 
}; 
+0

あなたはカスタマイズされたスロットからどのように価値を得ましたか? "event.slots。 .value"という値を取得しようとしたときにエラーが発生しました。私も "event.request.type.slots.value"を試しました。 – seleniumlover

関連する問題