AWS Lambda NodeJS 写入 S3 在本地和服务器上的行为不同 [英] AWS Lambda NodeJS writing to S3 behaves differently on local and sever

查看:15
本文介绍了AWS Lambda NodeJS 写入 S3 在本地和服务器上的行为不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用无服务器创建了一个 NodeJS Lambda 函数.它从 DynamoDB 表中读取数据并将数据写入 S3 存储桶.

I created a NodeJS Lambda function with Serverless. It reads from a DynamoDB table and writes the data to a S3 bucket.

这是我的 handler.js:(显示受影响的函数):

Here's my handler.js: (showing the affected function):

module.exports.exportContactsByClientID = (event, context, callback) => {
  // const id = event.pathParameters.id.toLowerCase();
  const id= 'mkh';
  
  const params = {
    TableName: contactsTable,
    IndexName: "client_code-created_at_local-index",
    KeyConditionExpression: "client_code = :v_ID",
    ExpressionAttributeValues: {
      ":v_ID": id,
    },
    ProjectionExpression: "client_code, created_at, contact_name, age, phone, email, dsr_ratio, max_eligibility, selected_banks"
  };

return db.query(params)
.promise()
.then((res) => {
  // console.log(res);
  const items = res.Items;
  // Headers + Columns
  worksheet.cell(1, 1).string('Client').style({font: {bold: true}});
  worksheet.cell(1, 2).string('Name').style({font: {bold: true}});
  worksheet.cell(1, 3).string('Age').style({font: {bold: true}});
  worksheet.cell(1, 4).string('Email').style({font: {bold: true}});
  worksheet.cell(1, 5).string('Phone').style({font: {bold: true}});
  worksheet.cell(1, 6).string('DSR Ratio').style({font: {bold: true}});
  worksheet.cell(1, 7).string('Max Eligibility').style({font: {bold: true}});
  // Rows
  // items.sort((a, b) => (a.date > b.date) ? -1 : 1);
  items.forEach((item, i) => {
    console.log(item.contact_name);
    worksheet.cell(i + 2, 1).string(item.client_code);
    worksheet.cell(i + 2, 2).string(item.contact_name);
    worksheet.cell(i + 2, 3).string(item.age);
    worksheet.cell(i + 2, 4).string(item.email);
    worksheet.cell(i + 2, 5).string(item.phone);
    worksheet.cell(i + 2, 6).string(item.dsr_ratio);
    worksheet.cell(i + 2, 7).string(item.max_eligibility);
  });
  console.log(contactsBucket);
  console.log(id);
  workbook.writeToBuffer().then(buffer => {
    console.log('inside writetoubgger')
    var params = {
      Bucket: contactsBucket,
      Key: `contacts/mkh.xlsx`,
      Body: buffer,
      ACL: 'public-read'
    }
    S3.upload(params, function(err, data) {
      if (err) {
        console.log(err, err.stack);
      } else {
        // callback(null, response(200, res));
        callback(null, response(200, res));
      }
    });
  })
})
.catch((err) => callback(null, response(err.statusCode, err)));
};

我的serverless.yml:

service: mhub-dsr-calculator-api

plugins:
  - serverless-plugin-include-dependencies

package:
  exclude:
    - node_modules/**

custom:
  allowed-headers:
      - Content-Type
      - Authorization
      - X-Api-Token
      - X-Origin
      - X-Amz-Date
      - X-Amz-Security-Token
  settings:
    CONTACTS_TABLE: dsrcalculator-contacts-dev
    CONTACTS_BUCKET: mhub-dsrcalculator-contacts

provider:
  name: aws
  runtime: nodejs12.x
  environment: ${self:custom.settings}
  region: ap-southeast-1 
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - dynamodb:DescribeTable
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
        - dynamodb:Query
      Resource:
        - "arn:aws:dynamodb:${self:provider.region}:*:table/${self:custom.settings.CONTACTS_TABLE}"
    - Effect: "Allow"
      Action:
        - dynamodb:Query
      Resource:
        - "arn:aws:dynamodb:${self:provider.region}:*:table/${self:custom.settings.CONTACTS_TABLE}/index/client_code-created_at_local-index"
    - Effect: "Allow"
      Action:
       - "s3:*"
      Resource: 
       - "arn:aws:s3:::${self:custom.settings.CONTACTS_BUCKET}/*"

functions:
  createPost:
    handler: handler.createContact
    events:
    - http:
        path: /contact
        method: post
        cors: true
  updatePost:
    handler: handler.updateContact
    events:
    - http:
        path: /contact/{id}
        method: put
        cors: true
  getAllPosts:
    handler: handler.getAllContacts
    events:
    - http:
        path: /contacts
        method: get
        cors: true
  getContactsByClientID:
    handler: handler.getContactsByClientID
    events:
    - http:
        path: /contacts/{id}
        method: get
        cors: true
  exportContactsByClientID:
    handler: handler.exportContactsByClientID
    events:
    - http:
        path: /export/{id}
        method: get
        cors: true

resources:
  Resources:
    PostsTable:
      Type: AWS::DynamoDB::Table
      Properties:
        AttributeDefinitions:
        - AttributeName: "id"
          AttributeType: "S"
        - AttributeName: "client_code"
          AttributeType: "S"
        - AttributeName: "created_at_local"
          AttributeType: "S"
        KeySchema:
        - AttributeName: "id"
          KeyType: "HASH"
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TableName: ${self:custom.settings.CONTACTS_TABLE}
        

当我在本地调用函数时(使用 serverless invoke local -f exportContactsByClientID)得到以下输出,其中mhub-dsrcalculator-contacts"是存储桶名称,mkh"是 id 和'inside writetoubgger' 表示 workbook.writeToBuffer 内的代码运行.

I get the following output when I invoke the function locally (with serverless invoke local -f exportContactsByClientID) where 'mhub-dsrcalculator-contacts' is the bucket name, 'mkh' is the id and 'inside writetoubgger' indicates the code inside workbook.writeToBuffer ran.

mhub-dsrcalculator-contacts
mkh
inside writetoubgger

S3 存储桶上的文件创建成功.

A file on S3 bucket is created successfully.

然而,当我部署它并进行测试时,尽管它连续运行,但代码并未进入workbook.writeToBuffer",如下所示.

However when I deploy this and test, though it runs to succession the code is not entering into 'workbook.writeToBuffer' as we can see below.

2020-06-22T11:23:22.945Z    1ce59a7b-98e4-4c9e-8736-ec7c162c4759    INFO    mhub-dsrcalculator-contacts
2020-06-22T11:23:22.945Z    1ce59a7b-98e4-4c9e-8736-ec7c162c4759    INFO    mkh
END RequestId: 1ce59a7b-98e4-4c9e-8736-ec7c162c4759

为什么会这样?任何指导将不胜感激.谢谢.

Why is this happening? Any guidance will be greatly appreciated. Thank you.

推荐答案

您的外部承诺正在完成,无需等待 writeToBuffer 承诺.

Your outer promise is finishing without waiting the writeToBuffer promise.

尝试改变:

workbook.writeToBuffer().then(...

收件人:

return workbook.writeToBuffer().then(...

您应该对 S3 上传调用执行相同的操作:

You should do the same to the S3 upload call:

return S3.upload(params).promise().then(data => {
        callback(null, response(200, res));
});

我还建议您使用 async/await 语法重写您的代码,这样更容易阅读和理解.

I would also recommend you rewrite your code using the async / await syntax, so it is easier to read and understand.

这篇关于AWS Lambda NodeJS 写入 S3 在本地和服务器上的行为不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆