Amazon web services 让Sequelize.js库在Amazon Lambda上运行

Amazon web services 让Sequelize.js库在Amazon Lambda上运行,amazon-web-services,aws-lambda,amazon-rds,serverless-framework,node-mysql2,Amazon Web Services,Aws Lambda,Amazon Rds,Serverless Framework,Node Mysql2,因此,我尝试在amazon上运行lambda,并最终通过在amazon测试控制台中测试lambda来缩小错误范围 我得到的错误是这个 { "errorMessage": "Please install mysql2 package manually", "errorType": "Error", "stackTrace": [ "new MysqlDialect (/var/task/node_modules/sequelize/lib/dialects/mysql/inde

因此,我尝试在amazon上运行lambda,并最终通过在amazon测试控制台中测试lambda来缩小错误范围

我得到的错误是这个

{
  "errorMessage": "Please install mysql2 package manually",
  "errorType": "Error",
  "stackTrace": [
    "new MysqlDialect (/var/task/node_modules/sequelize/lib/dialects/mysql/index.js:14:30)",
    "new Sequelize (/var/task/node_modules/sequelize/lib/sequelize.js:234:20)",
    "Object.exports.getSequelizeConnection (/var/task/src/twilio/twilio.js:858:20)",
    "Object.<anonymous> (/var/task/src/twilio/twilio.js:679:25)",
    "__webpack_require__ (/var/task/src/twilio/twilio.js:20:30)",
    "/var/task/src/twilio/twilio.js:63:18",
    "Object.<anonymous> (/var/task/src/twilio/twilio.js:66:10)",
    "Module._compile (module.js:570:32)",
    "Object.Module._extensions..js (module.js:579:10)",
    "Module.load (module.js:487:32)",
    "tryModuleLoad (module.js:446:12)",
    "Function.Module._load (module.js:438:3)",
    "Module.require (module.js:497:17)",
    "require (internal/module.js:20:19)"
  ]
}
我注意到当我部署sls时,它似乎只是打包了一些模块

Serverless: Package lock found - Using locked versions
Serverless: Packing external modules: babel-runtime@^6.26.0, twilio@^3.10.0, qs@^6.5.1, mailgun-js@^0.13.1, sequelize@^4.31.2, minimi
st@^1.2.0, uuid@^3.1.0
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Validating template...
Serverless: Updating Stack...

Serverless: Checking Stack update progress...
................................
Serverless: Stack update finished...
我想这就是它不起作用的原因简言之,我如何让mysql2库正确地与serverless打包,以便我的lambda函数与sequelize库一起工作?

请注意,当我在本地测试时,我的代码运行良好。

下面是我的无服务器文件

service: testapi

# Use serverless-webpack plugin to transpile ES6/ES7
plugins:
  - serverless-webpack
  - serverless-plugin-scripts
  # - serverless-domain-manager

custom:
  #Define the Stage or default to Staging.
  stage: ${opt:stage, self:provider.stage}
  webpackIncludeModules: true
  #Define Databases Here
  databaseName: "${self:service}-${self:custom.stage}"
  #Define Bucket Names Here
  uploadBucket: "${self:service}-uploads-${self:custom.stage}"
  #Custom Script setup
  scripts:
    hooks:
      #Script below will run schema changes to the database as neccesary and update according to stage.
      'deploy:finalize':  node database-schema-update.js --stage ${self:custom.stage}
  #Domain Setup
  # customDomain:
  #    basePath: "/"
  #    domainName: "api-${self:custom.stage}.test.com"
  #    stage: "${self:custom.stage}"
  #    certificateName: "*.test.com"
  #    createRoute53Record: true

provider:
  name: aws
  runtime: nodejs6.10
  stage: staging
  region: us-east-1
  environment:
    DOMAIN_NAME: "api-${self:custom.stage}.test.com"
    DATABASE_NAME: ${self:custom.databaseName}
    DATABASE_USERNAME: ${env:RDS_USERNAME}
    DATABASE_PASSWORD: ${env:RDS_PASSWORD}
    UPLOAD_BUCKET: ${self:custom.uploadBucket}
    TWILIO_ACCOUNT_SID: ""
    TWILIO_AUTH_TOKEN: ""
    USER_POOL_ID: ""
    APP_CLIENT_ID: ""
    REGION: "us-east-1"
    IDENTITY_POOL_ID: ""
    RACKSPACE_API_KEY: ""
  #Below controls permissions for lambda functions.
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:DescribeTable
        - dynamodb:UpdateTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn:aws:dynamodb:us-east-1:*:*"

functions:
  create_visit:
    handler: src/visits/create.main
    events:
      - http:
          path: visits
          method: post
          cors: true
          authorizer: aws_iam
  get_visit:
    handler: src/visits/get.main
    events:
      - http:
          path: visits/{id}
          method: get
          cors: true
          authorizer: aws_iam
  list_visit:
    handler: src/visits/list.main
    events:
      - http:
          path: visits
          method: get
          cors: true
          authorizer: aws_iam
  update_visit:
    handler: src/visits/update.main
    events:
      - http:
          path: visits/{id}
          method: put
          cors: true
          authorizer: aws_iam
  delete_visit:
    handler: src/visits/delete.main
    events:
      - http:
          path: visits/{id}
          method: delete
          cors: true
          authorizer: aws_iam
  twilio_send_text_message:
    handler: src/twilio/twilio.send_text_message
    events:
      - http:
          path: twilio/sendtextmessage
          method: post
          cors: true
          authorizer: aws_iam
  #This function handles incoming calls and where to route it to.
  twilio_incoming_call:
    handler: src/twilio/twilio.incoming_calls
    events:
      - http:
          path: twilio/calls
          method: post
  twilio_failure:
    handler: src/twilio/twilio.twilio_failure
    events:
      - http:
          path: twilio/failure
          method: post
  twilio_statuschange:
    handler: src/twilio/twilio.statuschange
    events:
      - http:
          path: twilio/statuschange
          method: post
  twilio_incoming_message:
    handler: src/twilio/twilio.incoming_message
    events:
      - http:
          path: twilio/messages
          method: post
  twilio_whisper:
    handler: src/twilio/twilio.whisper
    events:
      - http:
          path: twilio/whisper
          method: post
      - http:
          path: twilio/whisper
          method: get
  twilio_start_call:
    handler: src/twilio/twilio.start_call
    events:
      - http:
          path: twilio/startcall
          method: post
      - http:
          path: twilio/startcall
          method: get

resources:
  Resources:
    uploadBucket:
       Type: AWS::S3::Bucket
       Properties:
         BucketName: ${self:custom.uploadBucket}
    RDSDatabase:
      Type: AWS::RDS::DBInstance
      Properties:
        Engine : mysql
        MasterUsername: ${env:RDS_USERNAME}
        MasterUserPassword: ${env:RDS_PASSWORD}
        DBInstanceClass : db.t2.micro
        AllocatedStorage: '5'
        PubliclyAccessible: true
        #TODO: The Value of Stage is also available as a TAG automatically which I may use to replace this manually being put here..
        Tags:
          -
            Key: "Name"
            Value: ${self:custom.databaseName}
      DeletionPolicy: Snapshot
    DNSRecordSet:
      Type: AWS::Route53::RecordSet
      Properties:
        HostedZoneName: test.com.
        Name: database-${self:custom.stage}.test.com
        Type: CNAME
        TTL: '300'
        ResourceRecords:
        - {"Fn::GetAtt": ["RDSDatabase","Endpoint.Address"]}
      DependsOn: RDSDatabase
更新::所以我确认运行sls包--stage dev似乎会在最终上传到AWS的zip文件夹中创建它这确认serverless由于某种原因没有使用mysql2引用正确创建包这是为什么?

请求的网页包配置文件

const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");

module.exports = {
  entry: slsw.lib.entries,
  target: "node",
  // Since 'aws-sdk' is not compatible with webpack,
  // we exclude all node dependencies
  externals: [nodeExternals()],
  // Run babel on all .js files and skip those in node_modules
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        include: __dirname,
        exclude: /node_modules/
      }
    ]
  }
};

感谢dashmugs在本页()上进行一些调查后发表的评论,这里有一个关于强制包含的部分。我在这里解释一下

强制包含有时可能会使用动态 在您的代码中需要,即您需要的模块仅在 运行时。Webpack无法检测此类外部和已编译的 包将丢失所需的依赖项。在这种情况下,您可以强制 该插件通过在 forceInclude数组属性。但是,该模块必须显示在您的 package.json中服务的生产依赖项

所以我就这么做了

webpackIncludeModules:
    forceInclude:
      - mysql
      - mysql2

现在它工作了!希望这能帮助其他人解决同样的问题。

以前的解决方案都没有帮助过我,我使用了以下解决方案:

诀窍是使用
方言模块
属性并覆盖sequelize

import Sequelize from 'sequelize';
import mysql2 from 'mysql2'; // Needed to fix sequelize issues with WebPack

const sequelize = new Sequelize(
  process.env.DB_NAME,
  process.env.DB_USER,
  process.env.DB_PASSWORD,
  {
    dialect: 'mysql',
    dialectModule: mysql2, // Needed to fix sequelize issues with WebPack
    host: process.env.DB_HOST,
    port: process.env.DB_PORT
  }
)

export async function connectToDatabase() {
  console.log('Trying to connect via sequelize')
  await sequelize.sync()
  await sequelize.authenticate()
  console.log('=> Created a new connection.')

  // Do something 
}

到目前为止,前面的版本可以在MySql上使用,但不能在Postgres上使用。您可能需要添加
mysql2
作为外部模块。你能展示你的
webpack.config.js
吗?当然,我正在使用无服务器,所以我想看看他们把它藏在哪里了。好的,把它添加到我问题的底部
webpackIncludeModules:
    forceInclude:
      - mysql
      - mysql2
import Sequelize from 'sequelize';
import mysql2 from 'mysql2'; // Needed to fix sequelize issues with WebPack

const sequelize = new Sequelize(
  process.env.DB_NAME,
  process.env.DB_USER,
  process.env.DB_PASSWORD,
  {
    dialect: 'mysql',
    dialectModule: mysql2, // Needed to fix sequelize issues with WebPack
    host: process.env.DB_HOST,
    port: process.env.DB_PORT
  }
)

export async function connectToDatabase() {
  console.log('Trying to connect via sequelize')
  await sequelize.sync()
  await sequelize.authenticate()
  console.log('=> Created a new connection.')

  // Do something 
}