AWS Lambdaのpythonで複数テーブル引いてきて検索するやつ作った
ちょっと融通の利く検索システムがほしかったので作成、
無謀にもpython3.6で挑戦、ここを参考にスタートしたのはいいものの
初心者の上あほなので調べながらやってたのでここまでで1週間位かかっている。
DynamoDBのテーブル構造は以下の通りです。
テーブル1のKEYで検索した結果を使ってテーブル2のPKを特定し
そして検索結果をJSONで返すというやつです。
テーブル1でカテゴリから商品コードを引いてきて、その商品コードと
Webから受け取ったパラメータで検索を行って検索結果を一覧で
表示するとかいう内容を想定しています。こうしておけば
VALUEの部分が可変でも対応できるので柔軟かなぁと考えてのことです。
テーブル1:
----------------------------------
KEY,VALUE
----------------------------------
VALUE[n],SEARCHKEY,VALUE
----------------------------------
※VALUE[n]はテーブル1のVALUEです。
イメージとしては[KEY]→テーブル1からVALUE取得
[VALUE[n]]+[SEARCHKEY]→テーブル2からVALUE取得
LambdaはWebのエディタで作るという無謀感が半端ない。メンテナンス性とか全く考慮なし。本当はこういうのでやるべきですが、使い方が分かりません。
どなたか親切な方、教えてください。
でお約束のソース共有
相変わらずエラー処理はザルみたいな感じで不安が残る。APIGateWayで500エラー
返したかったんでここ参考にソース少し修正したのとAPIGateway設定しました。
これだからダメなんですがな、とりあえずはskの部分とctのところはAPIGateWayから
値を受けて可変にさせる想定です。辞書型とLambdaが返してくるのがリストになっていてそこから値を取り出してまたリストに放り込むところが悩んだ悩んだ。
pythonってインデントでSyntaxチェックしたりで結構癖が強いですが
コード自体は初心者が書いても結構シンプルに読みやすくなるのでいいかも
しれないです。とりあえずSAMとかはきちんと勉強した方がいいカモなぁ
無謀にもpython3.6で挑戦、ここを参考にスタートしたのはいいものの
初心者の上あほなので調べながらやってたのでここまでで1週間位かかっている。
DynamoDBのテーブル構造は以下の通りです。
テーブル1のKEYで検索した結果を使ってテーブル2のPKを特定し
そして検索結果をJSONで返すというやつです。
テーブル1でカテゴリから商品コードを引いてきて、その商品コードと
Webから受け取ったパラメータで検索を行って検索結果を一覧で
表示するとかいう内容を想定しています。こうしておけば
VALUEの部分が可変でも対応できるので柔軟かなぁと考えてのことです。
テーブル1:
----------------------------------
KEY,VALUE
----------------------------------
テーブル2:
----------------------------------VALUE[n],SEARCHKEY,VALUE
----------------------------------
※VALUE[n]はテーブル1のVALUEです。
イメージとしては[KEY]→テーブル1からVALUE取得
[VALUE[n]]+[SEARCHKEY]→テーブル2からVALUE取得
LambdaはWebのエディタで作るという無謀感が半端ない。メンテナンス性とか全く考慮なし。本当はこういうのでやるべきですが、使い方が分かりません。
どなたか親切な方、教えてください。
でお約束のソース共有
import logging import json import os import re import boto3 from boto3.dynamodb.conditions import Key class InternalFunctionError(Exception): def __init__(self, code, messages): self.code = code self.messages = messages def __str__(self): exobj = { 'error': { 'code': self.code, 'messages': self.messages } } return json.dumps(exobj) def get_code(id,keyname,tablename): try: dynamodb = boto3.resource('dynamodb') table = dynamodb.Table(tablename) response = table.get_item( Key={ keyname:id } ) return response['Item'] except Exception as e: LOGGER.error(traceback.format_exc()) raise InternalFunctionError( 500,[{'message': 'InternalServerError'}] ) def get_item_val(id1,id2,key1,key2,tablename): try: dynamodb = boto3.resource('dynamodb') table = dynamodb.Table(tablename) response = table.query( KeyConditionExpression=Key(key1).eq(id1) & Key(key2).eq(id2) ) return response['Items'] except Exception as e: LOGGER.error(traceback.format_exc()) raise InternalFunctionError( 500,[{'message': 'InternalServerError'}] ) def lambda_handler(event, context): try: sk = '1010' ct = '4' t1 = os.getenv('TABLE_NAME1') k1 = os.getenv('KEY_NAME1') t2 = os.getenv('TABLE_NAME2') k21 = os.getenv('KEY_NAME21') k22 = os.getenv('KEY_NAME22') item = get_code(ct,k1,t1) result=[] for i_key,i_val in item.items(): m = re.match(k1,i_key) if (m is None): item_content = get_item_val(i_val,sk,k21,k22,t2) if(len(item_content) is not 0): s=item_content[0] result.append(s) return result except Exception as e: LOGGER.error(traceback.format_exc()) raise InternalFunctionError( 500,[{'message': 'InternalServerError'}] )
相変わらずエラー処理はザルみたいな感じで不安が残る。APIGateWayで500エラー
返したかったんでここ参考にソース少し修正したのとAPIGateway設定しました。
これだからダメなんですがな、とりあえずはskの部分とctのところはAPIGateWayから
値を受けて可変にさせる想定です。辞書型とLambdaが返してくるのがリストになっていてそこから値を取り出してまたリストに放り込むところが悩んだ悩んだ。
pythonってインデントでSyntaxチェックしたりで結構癖が強いですが
コード自体は初心者が書いても結構シンプルに読みやすくなるのでいいかも
しれないです。とりあえずSAMとかはきちんと勉強した方がいいカモなぁ
コメント
インサートはあっさりできるな。
import boto3
import json
import os
import re
from boto3.dynamodb.conditions import Key
import datetime
import time
import random
dynamodb = boto3.resource('dynamodb')
def insert_log(category,searchkey,logtablename):
try:
cd = datetime.datetime.now()
#KEY生成
t = time.time()
r=random.randint(1,10)
tkey = str(t) + str(r)
#print(createdate)
table = dynamodb.Table(logtablename)
response = table.put_item(
Item = {
'key-id': tkey,
'category': category,
'search-key':searchkey,
'createdate':str(cd)
}
)
return
except Exception as e:
print(e)
raise e
def get_code(id,keyname,tablename):
try:
table = dynamodb.Table(tablename)
response = table.get_item(
Key={
keyname:id
}
)
return response['Item']
except Exception as e:
print(e)
raise e
def get_item_val(id1,id2,key1,key2,tablename):
try:
table = dynamodb.Table(tablename)
response = table.query(
KeyConditionExpression=Key(key1).eq(id1) & Key(key2).eq(id2)
)
return response['Items']
except Exception as e:
print(e)
raise e
def lambda_handler(event, context):
try:
sk = '1010' #商品検索条件
ct = '4' #商品カテゴリ
t1 = os.getenv('TABLE_NAME1')
k1 = os.getenv('KEY_NAME1')
t2 = os.getenv('TABLE_NAME2')
k21 = os.getenv('KEY_NAME21')
k22 = os.getenv('KEY_NAME22')
lt = os.getenv('LOG_TABLE')
#検索条件をログレコードに書込み
putlog = insert_log(sk,ct,lt)
#商品コードを取得して検索結果を取得する
item = get_code(ct,k1,t1)
result=[]
for i_key,i_val in item.items():
m = re.match(k1,i_key)
if (m is None):
#商品コード+検索キーで検索
item_content = get_item_val(i_val,sk,k21,k22,t2)
if(len(item_content) is not 0):
#print(item_content)
s=item_content[0]
result.append(s)
return result
except Exception as e:
print(e)
raise e