#はじめに
ヤフオクでの出品物の在庫管理を任されたのでサーバーレスで自動化しました。
流れとしては、出品→在庫へ登録→csvに出力というものです。
最終的に印刷して保存するためにエクセルで開けるようにcsvに出力します。
AWS Lambdaで自動でこの流れを実行できるようにします。
#TL;DR
- pythonでスクレイピング。DynamoDBに登録
- DynamoDBのデータを元にcsv生成、AWS S3にアップロード
- URLにアクセスすると最新版のデータが取得できる
この流れで実行されます。
今回のリポジトリ
ramo798/Inventory_control
#ポイント
##boto3でのupdate_itemメソッドの予約語に引っかかる
response = table.update_item(
Key={
'model_number': model_number
},
UpdateExpression="set url = :url",
ExpressionAttributeValues={
':url':"https://test.com/"
},
ReturnValues="UPDATED_NEW"
)
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the UpdateItem operation: Invalid UpdateExpression: Attribute name is a reserved keyword; reserved keyword: url
UpdateExpression="set url = :url"
とすると上記のエラーとなるので、UpdateExpression="set item_url = :url"
と書き換えることでことなきを得た。
##LambdaのAMIロールの設定
- AmazonDynamoDBFullAccess
- AWSLambdaDynamoDBExecutionRole
の二つの指定を指定しないとdynamoに書き込みができない
##Lambdaでcsvをs3にアップロードするのに手間取った
with open('csv/tomokimi_777.csv', 'w', newline="") as f:
と記述すると
"errorMessage": "[Errno 30] Read-only file system: 'csv/tomokimi_777.csv'",
Read-only
だと怒られてしまうので、with open
を使わずにCSVを生成しないといけなかった。
row = ""
fieldnames = 'タイトル,価格' + "/n"
row += "タイトル," + "2000," + "/n"
のように地道に一つのstrとして生成した。
ちなみに価格を2,000
と記述すると,
がcsvの区切りと認識されて面白いことになった。
##S3へのアップロード周り
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('bucket_name')
def upload_csv(items):
srt_csv = "タイトル,価格/n タイトル,2000/n"
objkey = 'file.csv'
putobj = bucket.Object(objkey)
putobj.put(Body=str_csv)
これでしっかりと上書き更新されていた。
#今後
- スクレイピングに時間がかかっているので何らかの方法で高速化を検討しないといけない。(現在ローカルでは5分、Lambda上では15分近くかかっているので2つの関数に分けて上限に達しないようにしている)
- デプロイまで全てコマンドラインで行いたかったが、今回は手動でzipで固めてデプロイする手法を取っていたので、次にLambdaで開発を行うときはテストを含めてローカルで行い、コマンドでデプロイまで行いたい。