AWS Lambda NodeJS 写入 S3 在本地和服务器上的行为不同 [英] AWS Lambda NodeJS writing to S3 behaves differently on local and sever
问题描述
我使用无服务器创建了一个 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屋!