2017-03-04 57 views
6

我的AWS Lambda函数中有一个查询我的MySQL数据库(从AWS远程托管)的问题。从NodeJS查询MySQL数据库AWS Lambda函数

这是我的代码,除了我需要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 

我使用的是通过NPM与index.js目录中安装了“MySQL的”模块和压缩,并将其上传到我的lambda表达式。

再一次,这在我的开发机器上工作,但在测试我的Lambda函数时没有指示符,因为它根本不影响我的数据库。

我的问题扩展到Alexa和Lambda中,就像正确使用mysql Node.JS模块一样。

这是我当前的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 
+0

您应该运行在连接回调中查询。在这里,你将'connect()'看作是同步的,它并不是这样,所以当你运行'query()'时,你可能会也可能不会连接,这在偶然的地方适用于你。你也忽略了'query()'可能提供的任何错误。 –

+0

我是否也应该在回调中结束连接? –

+0

我更新了我的问题,提供了更多关于我的问题的全部信息,并通过将我的查询放入我的连接回调中添加了我的意思。我会尽快处理我的函数的错误处理,只要我可以将它发布到我的MySQL数据库中,因为据我所知,测试lambda函数时我不会得到控制台输出,所以它会是此时略微无益。 –

回答

3

的问题是,我需要把我的CON text.succeed在我的回调里面。非常感谢sqlbot,因为他对回调的讨论导致我研究事情实际结束执行的地方。

很显然,当使用AWS Lambda时,如果“上下文”在您的回调被调用之前结束,则不会得到回调。所以即使我把所有的回调都放在了这样的位置:connect - > query - > end,连接的第一个回调函数从不会被调用,因为之后会调用“context.succeed”,从而结束执行。

这里是我的代码截至目前(得到一个正确的查询现在发生的事情):

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