본문 바로가기
API/MySQL API

Python으로 Mysql접속, 사진 업로드&오토태깅&DB저장 API, 포스팅 수정&DB수정 API

by 하니__ 2024. 5. 29.

 

 

사진 업로드, 오토태깅, DB에 저장을 해보자

 

사진 업로드 API, boto3

 AWS - 객체 감지 API

 

이전글 참고 바라며

둘의 짬뽕 + DB에 저장까지 하자

 

API 설정

 

우선 HTTP 메소드는 

CRUD중 Create에 해당하는

POST로 설정

 

경로는 포스팅 하는 거라서 /post로 지정해줬다

그리고 회원가입, 로그인 인증토큰을 받을 예정이라

 

헤더에서 인증토큰을 넣어줘야 하고

 

body에서 사진업로드와

사진과 함께 텍스트 컨텐트를 넣어준다

 

app.py 설정
api.add_resource( PostResource ,'/post')

 

간단히 경로를 설정해 준다

 

post.py 설정

 

 

이 부분은 길어지니

 

사진 업로드 API, boto3

 AWS - 객체 감지 API

 

 

우선 이 부분을 참고 바라며

 

try:
    client.upload_fileobj(file,
                        Config.S3_BUCKET,
                        file_name,
                        ExtraArgs = {"ACL":"public-read",
                                    "ContentType": file.content_type})
except Exception as e:
    return{"error": str(e)}, 500

label_list = self.detect_labels(file_name,Config.S3_BUCKET)
imgUrl = Config.S3_URL + file_name

이 부분 아래 부터 시작한다

 

앞선 과정에서

 

이미지를 업로드 했고,

이미지를 분석해서 태그에 넣을것들도 자동으로 얻었다

 

이제 DB에 넣어야 하는데

다시 try 하여 DB에 넣어주자

try :
    connection = get_connection()
    userId = get_jwt_identity()
    query = '''insert into post
            (userId, imgUrl, content, tag)
            value
            (%s, %s, %s, %s);'''
    record = (userId, imgUrl, content,','.join(label_list))

    cursor = connection.cursor()
    cursor.execute(query,record)
    connection.commit()
    cursor.close()
    connection.close()

DB에 연결해서

jwt 토큰으로부터 유저아이디를 가져와

DB에 저장해야하는 데이터들을 쿼리에 적어준다

이때 이미지URL은 위에서 변수로 이미 만들어 주었고,

사진과 함께 작성될 텍스트는

request.form을 이용하여 이미 content라는 이름의 변수로 지정,

그리고 태그는 객체감지 API를 사용하여 이미 만들어진

label_list를 ','.join(label_list) 으로 만들어 줘야 하는데

이는

 

INSERT INTO를 사용하여 데이터를 삽입할 때,

즉,

데이터베이스에 저장될 데이터 형식을 맞추기 위해 사용한다

label_list 는 ['cat', 'animal', 'pet'] 이런 형태의

리스트 형태를 이루고 있는데

데이터 베이스에 저장할때에는 문자열 형태로 넣어야 하기 때문에

','.join(label_list)를 사용하여

'cat,animal,pet' 형태의 문자열로 만들어주는것이다

 

이렇게 하면

이렇게 링크와, 내용, 자동으로 지정한 태그가 나오게 되고

DB에도 저장되게 된다

 

 

 

여기까지는 태그 테이블이 따로 없을때의 이야기

 

보통은 태그테이블이 따로 있어

 

같은 태그들의 비슷한 사진들을 확인 할 수 있다

그래서 태그테이블을 따로 만들어야 한다

 

 

 

 

그래서 태그테이블과

포스팅_태그 테이블을 만들어준다

 

그리고 위의 코드들을 수정, 추가 해준다

 

수정
query = '''insert into post
                    (userId, imgUrl, content)
                    values
                    (%s, %s, %s);'''
record = (userId, imgUrl, content)

 

DB에 저장하는 쿼리에서 태그 관련을 지워준다

 

추가

 

 

cursor = connection.cursor()
cursor.execute(query,record)

바로 윗 부분 이 부분 다음 부분 부터 추가 한다

 

우선은 리스트 형태로 되어 있는 레이블 리스트로 부터

 

하나하나 빼와서

태그테이블에 존재하는지 확인,

존재한다면 태그 아이디를 가져오고

존재하지 않는다면 insert into 한 뒤에

태그아이디를 가져오고

 

그 뒤에 포스팅 태그 테이블에

 

포스팅 아이디와 태그 아이디를 넣어줘야 한다

 

그렇다면

 

for label in label_list:

    query = '''select *
                from tag
                where name = %s;'''
    record = (label, )
    cursor = connection.cursor(dictionary=True)
    cursor.execute(query,record)
    result_list = cursor.fetchall()

    if len(result_list) == 1 :
        tag_id = result_list[0]['id']
    else :
        query = '''insert into tag
                    (name)
                    values
                    (%s);'''
        record = (label, )
        cursor = connection.cursor()
        cursor.execute(query,record)
        tag_id = cursor.lastrowid

    query = '''insert into posting_tag
                (postId,tagId)
                values
                (%s, %s);'''
    record = ( post_id , tag_id)
    cursor = connection.cursor()
    cursor.execute(query, record)

for 반복문으로 레이블리스트에서 레이블을 하나하나 꺼내와서

태크 테이블에 있는지 확인하는 쿼리문을 작성

확인 한다 이후

if 조건문을 활용 있다면 태그아이디를 가져오고

없다면 다시 저장하는 쿼리문을 작성후

마지막행의 태그 아이디를 가져온다

 

즉 두가지 경우 모두 태그아이디를 가져왔으니

이제 포스팅태그 테이블에 포스트아이디와 태그아이디를 등록

 

해준뒤에

 

 

윗부분에서 반복문 시작하기 전 그 구간에

post_id = cursor.lastrowid

이 문구 도 추가해준다

 

그리고나서

connection.commit()
cursor.close()
connection.close()

이제서야 커밋을 하고 종료하도록 하자

 

 

그렇게 진행된다면

 

결과를 알려줌은 동시에

포스트 테이블

태그 테이블

포스팅태그 테이블 모두 등록이 되는것을 확인 할 수 있다

 

 

 

 

 

이때 이것을 수정하는 API를 만들려고 한다면

HTTP 메소드를 PUT로 수정,

그리고 경로에서 포스팅ID를 지정해준뒤

try :

    connection = get_connection()
    userId = get_jwt_identity()
    query = '''update post
                set imgUrl = %s,
                    content = %s,
                where id = %s and userId = %s; '''

    record = (imgUrl,
              content,
              postId,
              userId)

 

DB에 수정하는 쿼리 부분만 수정,

 

태그네임을 for 반복문으로 넣어주는 과정 중에서

tag_id = cursor.lastrowid

# 같은 포스트아이디와 태그아이디가 존재하는지 체크
query = '''select * 
            from posting_tag
            where postId = %s
            and tagId = %s;'''
record = (post_id, tag_id)
cursor.execute(query, record)
result_list = cursor.fetchall()

if len(result_list) == 0:
    # 존재하지 않다면 추가
    query = '''insert into posting_tag
                (postId, tagId)
                values
                (%s, %s);'''
    record = (post_id, tag_id)
else:
    # 존재 한다면 수정
    query = '''update posting_tag
                set tagId = %s
                WHERE postId = %s
                AND tagId = %s;'''
    record = (tag_id, post_id, result_list[0]['tagId'])
    cursor = connection.cursor()
    cursor.execute(query, record)

이렇게 쿼리문을 수정해준다

 

태그아이디를 받아온 시점부터

같은 포스트 아이디와 태그아이디 존재하는지 체크후에

존재하지 않다면 추가를 해주고

존재한다면 수정으로 간다

 

이 외의 코드는 전부 동일하다

기존에 9번까지였던 태그가 12번까지 추가 되었다

3가지가 변경되었다는 뜻