前提
S3にアップロードされたcsvを取り込む際
1行目を飛ばし2行目から読み込み
変換処理をかけようとした際に
エラーが発生した
実現したいこと
ここに実現したいことを箇条書きで書いてください。
- S3にアップロードされたcsvを読み込み
- 1行目(項目、ヘッダー)を飛ばし、2行目から読み込み
- 項目に応じた変換処理をかけOpensearchへ転送したい
発生している問題・エラーメッセージ
本Lamda(python)はトリガーを設定しています。
【トリガー】
S3にcsvがアップロードされることで、Lamda(python)が実行開始される
アップロードするcsv
vmanage_host, systemip, hostname , devicemodel, bfdSessionsUp, bfdSessions, datetime, IPsecTunnel vmanageABC, 123.456.789.012, vedgeABC, deviceABC, 1, 2, 3, 2022/1/1 01:01:01, 123
エラー(本題)
1行目が項目のため、型変換できないというエラーとなっている(と推察)
[Error] ValueError : invalid literal for int() with base 10: `ABC.csv`
該当のソースコード
Lamda(python)
1 2import boto3 3import re 4import requests 5import csv 6import io 7import BytesIO 8from requests_aws4auth import AWS4Auth 9 10#配列 11vmanage_host = [] 12systemip = [] 13hostname = [] 14devicemodel = [] 15bfdSessionsUp = [] 16bfdSessions = [] 17datetime = [] 18IPsecTunnel = [] 19 20 21region = '(略)' # e.g. us-west-1 22service = 'es' 23credentials = boto3.Session().get_credentials() 24awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token) 25 26host = '(略)' # the OpenSearch Service domain, e.g. https://search-mydomain.us-west-1.es.amazonaws.com 27index = 'lambda-s3-index' 28type = '_doc' 29url = host + '/' + index + '/' + type 30 31headers = { "Content-Type": "application/json" } 32 33s3 = boto3.client('s3') 34 35# Lambda execution starts here 36def handler(event, context): 37 for record in event['Records']: 38 #header = next(reader) ←検証③ 39 40 # Get the bucket name and key for the new file 41 bucket = record['s3']['bucket']['name'] 42 key = record['s3']['object']['key'] 43 44 # Get, read, and split the file into lines 45 obj = s3.get_object(Bucket=bucket, Key=key) 46 body = obj['Body'].read() 47 textIo = io.TextIOWrapper(io.BytesIO(body)) 48 #header = next(reader) ←検証① 49 50 # Match the regular expressions to each line and index the JSON 51 for row in lines csv.reader(textIo): 52 #header = next(reader) ←検証② 53 54 print(row) 55 vmanage_host = row[0] 56 systemip = row[1] 57 hostname = row[2] 58 devicemodel = row[3] 59 bfdSessionsUp = row[4] 60 bfdSessions = row[5] 61 datetime = row[6] 62 IPsecTunnel = row[7] 63 64 print(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]) 65 66 document = { 67 "vmanage_host ": vmanage_host , 68 "systemip ": systemip , 69 "hostname ": hostname , 70 "devicemodel ": devicemodel , 71 "bfdSessionsUp": [int(bfdSessionsUp)], 72 "bfdSessions ": [int(bfdSessions)], 73 "datetime ": [strftime(datetime)], 74 "IPsecTunnel ": [int(IPsecTunnel)], 75 } 76 r = requests.post(url, auth=awsauth, json=document, headers=headers)
試したこと
検証箇所①、②、③にそれぞれ以下のヘッダーを読み飛ばす処理を
いれて、確認したが、いずれの箇所も同様のメッセージとなり実行を
確認することができなかった。
header = next(reader)
補足情報(FW/ツールのバージョンなど)
Python3.8
エラーが発生しているのは以下で、
for record in event['Records']:
event に Records というキーがない、と表示されています。print(event.keys()) などとして、内容を確認してみてはどうでしょうか。
melianさん
コメントありがとうございます。
確認が遅れてすみません。現在確認中です。
melianさん
ご助言ありがとうございます。再度ご教授を頂きたく。
以下のそれぞれの箇所にいれたのですが、エラー内容は変わらず。
Print結果も表示されませんでした。挿入箇所はまちがいないでしょうか。
def handler(event, context):
for record in event['Records']:
print(event.keys()) ←挿入①
# Get the bucket name and key for the new file
bucket = record['s3']['bucket']['name']
print(event.keys()) ←挿入②
for 文の直前に入れてみて下さい。
def handler(event, context):
print(event.keys()) # ここに挿入
for record in event['Records']:
melianさん早いご回答ありがとうございます。
結果は以下となりました。Printつけてもつけなくても同様のエラー内容となっております。
Response
{
"errorMessage" : "`Records`",
"errorType" : "KeyError",
"requestId" : "(略)"
"stackTrace" : [
" File\" /var/task/sample.py\, line 39, inhander\n for record in event[`Records`]:\n"
]
}
AWS Lambda には詳しくないのでよく分かっていなのですが、print(event.keys()) の実行結果は AWS Cloud Watch の方に出力されているのではないでしょうか。
melianさん
ご指摘ありがとうございます。
お恥ずかしい限りです。CloudWatchに出力されておりました。
dict_keys([`key1`, `key2`, `key3`])
そうなりますと、やはり event には 'Records' というキーが存在しないということになりますね。。。
元ソースはこちらをベースにして改良してきました。
Amazon OpenSearch Service へのストリーミングデータをロードする - Amazon OpenSearch Service
https://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/integrations.html#integrations-s3-lambda
>event には 'Records' というキーが存在しないということ
すみません。この意図するところ、重要性が理解できておらず。。。
今回の問題は、Records というキーが存在しないために以下の部分(event['Records'])で必ずエラーが発生してしまうことなのです。
for record in event['Records']:
その Amazon OpenSearch Service の example code では確かに Records キーを参照しているので、、とここまで書いて気がついたのですが、example code の次に、
> region と host の変数を編集します。
と書かれています。こちらは編集済みでしょうか?
melianさん
> region と host の変数を編集します。
はい、こちら設定済みとなります。
セキュリティのため未記載としております。
重大なことを記載しておりませんでした。
こちらトリガーを設定しておりました。
トリガー
S3の csv/に「S3にアップロードされているcsv」がアップロードされると、本Lambdaが実行されます。
別途エラーが出てきたため整理致します。
melianさん
本来のエラー(型変換できない)
→回避するためのロジックの模索
を修正・追記いたしました。
エラー内容型変換できない
→1行目(項目)のため1行目を飛ばし、2行目から転送するロジックが必要
→header = next(reader) はcsvのみ?ストリーム形式では使用できない?
[Error] ValueError : invalid literal for int() with base 10: `ABC.csv`
回答1件
あなたの回答
tips
プレビュー