2017-03-04 8 views
6

Ich habe ein Problem bei der Abfrage meiner MySQL-Datenbank (gehostet von AWS aus) innerhalb meiner AWS Lambda-Funktion.Abfragen einer MySQL-Datenbank von einer NodeJS AWS-Lambda-Funktion

Dies ist mein Code mit Ausnahme der Teile I für den Rest Lambda-Funktion benötigen (was für eine Alexa Fähigkeit genannt wird):

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(); 

Dies funktioniert nur gut, wenn ich es mit dem Knoten laufen aus meiner Eingabeaufforderung:

node index.js 

ich bin mit dem „mysql“ Modul über npm im Verzeichnis mit index.js installiert und es zip und laden sie sie auf meine Lambda-Funktion.

Auch dies funktioniert auf meiner Entwicklungsmaschine, gibt aber keinen Hinweis auf meine Lambda-Funktion, warum sie meine Datenbank überhaupt nicht beeinflusst.

Meine Frage erstreckt sich in Alexa und Lambda ebenso wie die ordnungsgemäße Verwendung des mysql Node.JS-Moduls.

Hier ist mein aktueller Code für mein Lambda, und das Problem hier ist natürlich immer noch, dass mein Testwert -> ein Benutzername namens "TESTNAME" nicht zu meiner MySQL-Datenbank hinzugefügt wird.

Ich setze die Abfrage in den Connect-Callback, wie der erste Kommentar suggeriert, und ich setze meinen neuen Code, anstatt meinen alten Code oben zu aktualisieren, nur um zu dokumentieren, wie ich denke, dass der Code in den Übergang übergehen sollte Lambda-Funktion meine Alexa:

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

Und meine Konsole Ausgabe:

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

Sie sollten die Abfrage innerhalb der connect Rückruf ausgeführt werden. Hier behandeln Sie 'connect()' so, als wäre es irgendwie synchron, was nicht der Fall ist. Sie können also noch nicht verbunden sein, wenn Sie 'query() ausführen' Das funktioniert für Sie zufällig vor Ort. Du ignorierst auch irgendeinen Fehler, den 'query()' beeinflussen könnte. –

+0

Sollte ich die Verbindung auch innerhalb des Callbacks beenden? –

+0

Ich habe meine Frage mit weiteren Informationen zum vollen Umfang meiner Frage aktualisiert und hinzugefügt, was ich damit meine, indem ich meine Anfrage in meinen Connect-Rückruf einfüge. Ich werde mich um meine Fehlerbehandlung für meine Funktionen kümmern, sobald ich sie in meine MySQL-Datenbank schreiben kann, da ich, soweit ich weiß, beim Testen einer Lambda-Funktion keine Konsolenausgabe bekomme, so wäre es an dieser Stelle wenig hilfreich. –

Antwort

3

Das Problem war, dass ich brauchte, um meine con zu setzen text.succeed innerhalb meiner Rückrufe. Vielen Dank an sqlbot, denn seine Rede von Rückrufen veranlasste mich zu studieren, wo die Dinge tatsächlich ihre Ausführung beenden.

Also anscheinend bei der Verwendung von AWS Lambda, wenn der "Kontext" endet, bevor Ihre Rückrufe aufgerufen werden, erhalten Sie Ihre Rückrufe nicht. Obwohl ich alle Callbacks wie folgt platziert habe: connect -> query -> end, wird der erste Callback der Kette von connect nie aufgerufen, weil "context.succeed" gleich danach aufgerufen wurde, was die Ausführung beendete.

Hier ist mein Code ab jetzt (eine richtige Abfrage immer jetzt passiert):

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

Wie haben Sie den Wert aus dem benutzerdefinierten Steckplatz erhalten? Ich habe einen Fehler bekommen, als ich versuchte, den Wert als "event.slots. .value. Ich habe sogar versucht" event.request.type.slots.value ". – seleniumlover

Verwandte Themen