こんにちばガウタムです。
今回は、AWS Lambdaで、AWS SDK V3 を使ってS3からCSVファイルを取得して1行ごとにパースする方法について、ご紹介します。
検証のAWS LambdaはランタイムNode.js 20.xを利用してます。
まずは、必要なモジュールをインポートします。
import iconv from 'iconv-lite';
import parser from 'csv-parse'
import { Readable } from 'stream';
import { S3Client, GetObjectCommand, GetObjectCommandInput } from "@aws-sdk/client-s3";
次に、S3クライアントを作成します。
const s3Client = new S3Client({});
CSVファイルをパースする関数を定義します。この関数では、Shift-JISエンコーディングのCSVファイルを適切にデコードし、1行ごとにパースします。
async function parseFunc(fileData: any) {
const csvData = [];
const decoder = iconv.decodeStream('Shift_JIS');
const parse = fileData.pipe(decoder).pipe(parser());
for await (const record of parse) {
csvData.push(record);
}
return csvData;
}
次に、S3からCSVファイルを取得し、パースする処理を示します。
var file_data: any;
// S3からファイルを取得
let s3_param: GetObjectCommandInput = {
Bucket: YOUR_BUCKET_NAME,
Key: YOUR_KEY_NAME
}
try {
const getObjectCommand = new GetObjectCommand(s3_param);
const response = await s3Client.send(getObjectCommand)
file_data = Readable.from(response.Body);
} catch (error) {
console.log(`getObject error catched keyname=${key_name} error=${error}`);
throw error
}
let lines = await parseFunc(file_data);
if (lines == undefined) {
console.log('invalid file format. something wrongs with data');
const err = new Error('invalid file format. something wrongs with data');
throw err
}
// process all lines
await Promise.all(dataLines.map(async (line: any) => {
// process line
}));
まとめ
AWS SDK V3を使用してS3からCSVファイルを取得し、Shift-JISでエンコードされた各行をパースする方法について説明しました。iconv-lite、csv-parse、およびstreamモジュールを利用して、簡単に行ごとの処理が可能です。少しの工夫で、誰かの問題解決に役立てることができれば幸いです。