220823,

HyeonKi Jo·2022년 8월 23일
0

오늘의 할일

  • Cloud9을 통한 Python으로 RDS 접근하기
  • Cloud9코드 Lambda로 이식
  • Lambda 데이터 분석 다시해보기
  • Lambda 데이터 정리하기
  • S3 -> Lambda -> RDS 총 테스트
  • 데이터베이스 스키마 정리하기
  • 데이터베이스 스키마에 맞게 RDS저장하기
  • 보안 및 최소권한

Cloud9을 통한 Python으로 RDS 접근하기

Cloud9 생성

환경세팅

  • EC2, t2.micro, Amazon Linux2를 사용한다.
  • NEW-PUBLIC VPC와 그 서브넷 2a를 사용한다.

RDS 생성



  • 퍼블릭 액세스를 비허용함으로써 서브넷 내부에서만 접근이 가능하게한다.


Python으로 RDS 접속확인

sql_test.py

import sys
import logging
import rds_config
import pymysql
#rds settings
rds_host  = "rds-instance-endpoint"
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name

logger = logging.getLogger()
logger.setLevel(logging.INFO)

try:
    conn = pymysql.connect(host=rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
except pymysql.MySQLError as e:
    logger.error("ERROR: Unexpected error: Could not connect to MySQL instance.")
    logger.error(e)
    sys.exit()

logger.info("SUCCESS: Connection to RDS MySQL instance succeeded")
#def handler(event, context):
"""
This function fetches content from MySQL RDS instance
"""

item_count = 0

with conn.cursor() as cur:
    cur.execute("create table Employee ( EmpID  int NOT NULL, Name varchar(255) NOT NULL, PRIMARY KEY (EmpID))")
    cur.execute('insert into Employee (EmpID, Name) values(1, "Joe")')
    cur.execute('insert into Employee (EmpID, Name) values(2, "Bob")')
    cur.execute('insert into Employee (EmpID, Name) values(3, "Mary")')
    conn.commit()
    cur.execute("select * from Employee")
    for row in cur:
        item_count += 1
        logger.info(row)
        #print(row)
conn.commit()

print("Added %d items from RDS MySQL table" %(item_count))

rds_config.py

#config file containing credentials for RDS MySQL instance
db_username = "username"
db_password = "passoword"
db_name = "database name" 

실행

  • sudo pip install pymysql
    • pymysql을 설치해야한다.
  • 실행하면 다음과 같은 에러가 나온다. rds-cocudeny라는 데이터베이스가 없다.
    • 이는, 우리가 생성한 물리적(?)데이터베이스 안에 프로젝트와 같은 개념으로 공간적(?)데이터베이스를 만들어줘야 한다. 테이블들이 들어있는 데이터베이스를 만들어주는 느낌이다.
    • 하여튼 접근이 성공한 것이다.
  • bash에서 mysql명령어로 접근하면 접근이 되기 때문이다.
  • 위 에러는 이 databases에서 rds-database를 찾을 수 없다는 뜻이다.

해결

  • 여기서 초기 데이터베이스를 만들어준다.
  • 아래 자동백업은 테스트용이기때문에 빨리 생성하기위해 체크를 해제해줬다.
  • 테이블이 잘 생성되었다.
  • python 코드도 에러없이 실행되었다.
  • 테이블과 안에 데이터들도 잘 들어갔다.

Lambda에 이식하기

이슈1

  • pymysql은 추가적으로 설치해야하는 파이썬 모듈이다.
  • 하지만 lambda에서는 설치할 수 없어 이전에 실습에서는 도커 이미지를 사용했다.
  • 그러나 코드를 Zip파일로 압축해서 업로드하면 된다는글을 읽었다.
  • 그래서 사용하는 모듈폴더와 코드를 한번에 zip파일로 묶어 업로드해서 테스트를 해보도록 한다.
  • 다만 현재 프라이빗공간에서 Cloud9으로 작업하고 있기 때문에 S3를 통해 업로드하고 사용하도록 하겠다.

S3 생성

  • 이름: s3.cocudeny
  • ACL과 모든 퍼블릭 액세스를 비활성화 한다.
    • 현재 root계정이라 그런지 이렇게해도 접속할 수 있다.
  • zip파일을 계속 업로드 할것이기 때문에 버전관리옵션을 넣어준다.
  • 또, 암호화를 활성화하여 암호화한다.
  • lambda 소스코드를 담을 lambda_source라는 디렉토리를 생성했다.

Cloud9

  • pymysql 경로를 찾았다.
  • 우리의 작업 경로로 복사해준다.
  • zip -r lambda_source.zip *
  • 모듈파일, python코드 들이 있는 상태에서 zip파일을 만들어준다.
  • 오른쪽 test.py는 아님
  • zip파일이 생성되었다.
  • 이제 AWS S3로 cp해준다.
  • aws s3 cp lambda_source.zip s3://s3.cocudeny/lambda_source/lambda_source.zip
  • 잘 업로드 되었다.

이슈2

  • lambda_function을 찾을 수 없다는 에러.
  • 검색해보니 메인으로 사용하는 python파일의 이름은 lambda_function.py이어야 한다.
  • 수정해준다.

이슈3

  • Lambda의 기본 실행제한시간은 3초다. 매우 짧은시간이며 구성에서 최대 15분까지 연장시킬 수 있다.

이슈 4

  • RDS에 연결되지 않는다.
  • RDS의 엔드포인트를 넣는 환경변수를 생성해준다.
  • RDS는 프라이빗접근만 허용하기 때문에 Lambda의 VPC를 확인해본다.
  • VPC구성이 없다.
  • VPC와 서브넷 그리고 보안규칙을 설정해준다.
  • 실행역할을 먼저 설정해야한다.
  • 실행 역할에 EC2 create network 관련 정책을 추가하러간다.
  • https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-vpc.html
  • 우리의 람다는 다음과 같은 권한을 얻게되었다.
  • VPC가 잘 생성되었다.

이슈5

  • Employee 테이블이 이미 존재한다는 에러이다.
  • 테스트를 계속하느라 미리 생성되있는 것 같다.
  • 그러나 다음에도 같은 에러가 출력될 수 있으니 if not exists옵션을 넣어 중복생성을 막는다.
  • 또, Insert값에 Primary값을 가진 키가 있어서 Insert명령어를 주석처리해준다.
  • 결과 성공!

최종코드

import json
import sys
import logging
import rds_config
import pymysql
import os

#rds settings
rds_host  = os.environ['rds_host']
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name

logger = logging.getLogger()
logger.setLevel(logging.INFO)

try:
    conn = pymysql.connect(host=rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
    print('connected')
except pymysql.MySQLError as e:
    logger.error("ERROR: Unexpected error: Could not connect to MySQL instance.")
    logger.error(e)
    sys.exit()

logger.info("SUCCESS: Connection to RDS MySQL instance succeeded")

def lambda_handler(event, context):
    """
    This function fetches content from MySQL RDS instance
    """

    item_count = 0

    with conn.cursor() as cur:
        #cur.execute("create table if not exists Employee ( EmpID  int NOT NULL, Name varchar(255) NOT NULL, PRIMARY KEY (EmpID))")
        #cur.execute('insert into Employee (EmpID, Name) values(1, "Joe")')
        #cur.execute('insert into Employee (EmpID, Name) values(2, "Bob")')
        #cur.execute('insert into Employee (EmpID, Name) values(3, "Mary")')
        #conn.commit()
        cur.execute("select * from Employee")
        for row in cur:
            item_count += 1
            logger.info(row)
            #print(row)
    conn.commit()

    print("Added %d items from RDS MySQL table" %(item_count))
    return "Added %d items from RDS MySQL table" %(item_count)

Lambda 데이터 분석 다시해보기

이전 작업 리뷰

  • GCP Vision API에서 이미지에서 text를 가져온다.
  • 텍스트를 Pandas.DataFrame으로 정리하고, 위에서 아래로, 왼쪽에서 오른쪽으로 텍스트를 정렬했다.

크롤링

크롤링?

  • 라벨을 정의할 때, 각각의 다른 영양성분 라벨마다 다른 모양을 가지고 있다.
  • 그래서 좀더 다양한 라벨의 정보를 봐야한다는 생각이 들었다.
  • 오늘 시도해보다 어려워서 잠시 미룬다. ㅎ

데이터 분류하기

알러지 분류하기

def isKeyword(word):
  keyword_set = set(['계란', '우유', '땅콩', '견과류', '밀', '갑각류', '대두', '메밀', '육류', '생선', '과일'])
  for symbol in word.split(' '):
    if symbol in keyword_set:
      return True
  return False
  • 한 단어에서 법적으로 표기를 해야하는 알러지 정보 키워드가 존재하면 True를 반환하여 따로 뽑아낸다.
  • 결과는 다음과같이 잘...? 나왔다.
  • 여기서 Bool값이 아닌 알러지별 인덱스값으로 출력한다면 데이터베이스에 입력할 때 사용할 수 있다.

영양정보 분류하기

  • 영양정보의 라벨이다. 여기서 영양정보부터 Kcal 표시와 마지막 안내문구를 자르면 영양정보만 얻을 수 있다.
  • 위와같이 알러지 리스트, 영양정보 리스트로 나누었다.

정리

  • S3 삭제
  • Lambda함수 삭제
  • Cloud9 삭제
  • RDS 삭제

앞으로 할 일

  • 데이터 정리
  • S3 -> Lambda -> RDS 총 테스트
  • 데이터베이스 스키마 정리하기
  • 데이터베이스 스키마에 맞게 RDS저장하기
  • 보안 및 최소권한 정의
  • 마지막으로 이미지 분석 아키텍처 CI/CD화 하기
profile
Talking Potato

0개의 댓글