2017-03-04 19 views
6

Tôi đang gặp sự cố khi truy vấn cơ sở dữ liệu MySQL của mình (được lưu trữ từ xa từ AWS) bên trong hàm AWS Lambda của tôi.Truy vấn cơ sở dữ liệu MySQL từ hàm NodeJS AWS Lambda

Đây là mã của tôi ngoại trừ những phần tôi cần cho phần còn lại của chức năng Lambda (hiện đang được kêu gọi một kỹ năng 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(); 

này chỉ hoạt động tốt khi tôi chạy nó với nút từ của tôi nhắc lệnh:

node index.js 

Tôi đang sử dụng mô-đun "mysql" được cài đặt qua npm trong thư mục có index.js và nén nó và tải nó lên hàm Lambda của tôi.

Một lần nữa, điều này hoạt động trên máy phát triển của tôi, nhưng không đưa ra chỉ báo khi thử nghiệm hàm Lambda của tôi là tại sao nó không ảnh hưởng đến cơ sở dữ liệu của tôi.

Câu hỏi của tôi mở rộng sang Alexa và Lambda nhiều như việc sử dụng thích hợp mô-đun mysql Node.JS.

Đây là mã hiện tại của tôi cho Lambda của tôi, và vấn đề ở đây, tất nhiên, vẫn là giá trị thử nghiệm của tôi -> tên người dùng được gọi là "TESTNAME" không được thêm vào cơ sở dữ liệu MySQL của tôi.

Tôi đặt truy vấn vào cuộc gọi kết nối như nhận xét đầu tiên cho thấy và tôi đang đặt mã mới thay vì cập nhật mã cũ của mình ở trên để giữ hồ sơ về cách tôi nghĩ mã nên chuyển đổi thành chức năng của tôi Alexa của Lambda:

đang Cập nhật:

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

Và giao diện điều khiển đầu ra của tôi:

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

Bạn nên chạy truy vấn bên trong gọi lại kết nối. Ở đây, bạn đang xử lý 'connect()' như thể nó đã được đồng bộ bằng cách nào đó, nó không phải là, vì vậy bạn có thể hoặc có thể chưa được kết nối khi bạn chạy 'query()' Điều này làm việc cho bạn cục bộ một cách tình cờ. Bạn cũng bỏ qua bất kỳ lỗi nào 'query()' có thể là thuộc tính riêng tư. –

+0

Tôi có nên kết thúc kết nối bên trong cuộc gọi lại không? –

+0

Tôi đã cập nhật câu hỏi của mình với nhiều thông tin hơn về mức độ đầy đủ của câu hỏi của tôi và thêm những gì tôi nghĩ bạn có nghĩa là bằng cách đặt truy vấn của tôi vào cuộc gọi lại kết nối của tôi. Tôi sẽ xử lý việc xử lý lỗi cho các chức năng của mình ngay sau khi tôi có thể đăng nó lên cơ sở dữ liệu MySQL của mình, bởi vì tôi biết tôi không có được đầu ra console khi thử nghiệm hàm lambda, vì vậy nó sẽ hơi bất tiện vào thời điểm này. –

Trả lời

3

vấn đề là tôi cần phải đưa con tôi text.succeed bên trong callbacks của tôi. Rất cám ơn sqlbot, khi nói về callbacks đã dẫn tôi đến nơi mà mọi thứ đã thực sự kết thúc việc thực hiện của họ.

Vì vậy, rõ ràng khi sử dụng AWS Lambda, nếu "ngữ cảnh" kết thúc trước khi các cuộc gọi lại của bạn được gọi, bạn không nhận được cuộc gọi lại. Vì vậy, mặc dù tôi đã đặt tất cả các callback như sau: connect -> query -> end, callback đầu tiên của chuỗi từ kết nối không bao giờ được gọi vì "context.succeed" đã được gọi ngay sau đó, kết thúc thực hiện.

Dưới đây là mã của tôi như bây giờ (nhận được một truy vấn thích hợp xảy ra bây giờ):

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

Làm cách nào bạn nhận được giá trị từ vùng tùy chỉnh? Tôi gặp lỗi khi cố gắng lấy giá trị là "event.slots. .value. Tôi thậm chí đã thử" event.request.type.slots.value ". – seleniumlover

Các vấn đề liên quan