카테고리 없음

2024. 6. 14. (금) 슈퍼코딩 부트캠프 신입연수원 Day 11 (중간보고)

태영9922 2024. 6. 14. 18:09

 

  1. 중간 보고 양식(월~금요일)
  • TO-DO LIST : DB에 데이터를 저장하고 저장된 데이터를 가져오는 방법 학습
  • 배운 내용 요약 정리 

1. DB에서 BLOB 이란? Binary Large Object의 약자로, 텍스트나 숫자 같은 일반적인 데이터와 달리 이미지, 오디오, 비디오 등과 같은 데이터를 저장하기 위한 타입.

 

2. Form과 Annotated를 사용하기 위한 import

from fastapi import FastAPI, UploadFile, Form
from fastapi.staticfiles import StaticFiles
from typing import Annotated

2-1 프론트엔드에서 form에 있는 데이터를 보낼 것이기 때문에 Form 을 사용하였으며, 

@app.post("/items")
def create_item(
    image: UploadFile,
    title: Annotated[str, Form()],
    price: Annotated[int, Form()],
    description: Annotated[str, Form()],
    place: Annotated[str, Form()],
):

- Annotated를 사용한 이유는 매개변수의 타입힌트를 주기 위한 기능이며, 예를 들어 Annotated[str,Form()]이라는 키워드는 'str형식이고 Form()형태에서 받아오는 것이다' 라는 설명이다

 

3. 프론트엔드에서 fetch를 이용하여 post method로 서버에 요청

const handleSubmitForm = async (event) => {
  event.preventDefault();
  const body = new FormData(form); //body를 form 에서 입력되어 있는 값을 form 변수에 받아오고
  body.append("insertAt", new Date().getTime()); //insertAt이라는 별도의 변수를 넣기위해 append

  try {
    //에러처리
    const res = await fetch("/items", {
      method: "POST",
      body, //body : body 해도 되지만 생략해도 된다.
    });

    const data = await res.json();
    if (data === "200") 
      window.location.pathname = "/";
      //서버에서 정상적으로 완료되었을때 200을 return 해주도록 설계하였는데 만약 200이 return 된다면 root page로 이동하도록
    }
  } catch (e) {
    console.error("업로드에 실패했습니다");
  }
};

 

4. DB와 연결하기 위한 준비

import sqlite3
#sqlite3 모듈을 import

con = sqlite3.connect("db.db", check_same_thread=False) 
#db.db라는 DB파일과 연결하고, check_same_thread는 여러 스레드에서 사용할 수 있도록 하는 옵션인데, False로 지정해야 여러 스레드에서 사용 가능.

cur = con.cursor() 
#DB와 상호작용하기 위한 커서 객체를 생성. 이 객체를 이용하여 DB에서 쿼리를 실행하고 결과를 가져올 수 있음

 

5. DB에 데이터 삽입할 준비

image_bytes = await image.read()
#UploadFile객체로 표현된 image를 read하여 ByteString으로 반환.
#이후 이 ByteString을 DB에 저장하거나 처리할때 사용
  
  
cur.execute(f""" #f문자열을 사용하여 변수 및 쿼리문 실행
                INSERT INTO items (title, image, price, description, place)
                VALUES ('{title}','{image_bytes.hex()}',{price},'{description}','{place}')
              """)
con.commit() #DB 연결이 종료되더라도 트랜잭션을 DB에 반영하고 영구적으로 저장

1. 서버에 저장된 DB로부터 GET method 실행

const fetchList = async () => {
  const res = await fetch("/items");
  const data = await res.json();
  renderData(data);
};

 

2. 서버에서 클라이언트의 요청을 받아 프론트엔드로 넘겨주는 로직

from fastapi.responses import JSONResponse
from fastapi.encoders import jsonable_encoder


# 아이템 불러오기
@app.get("/items")
async def get_items():
    con.row_factory = sqlite3.Row  # 컬럼명도 같이 가져오는 문법
    cur = con.cursor() #쿼리문을 실행하기 위한 동작
    rows = cur.execute(
        f"""
                        SELECT * FROM items
                       """
    ).fetchall()

    return JSONResponse(jsonable_encoder(dict(row) for row in rows))
    #json 형태{key:value, key:value, ...} 형태로 반환하기 위한 동작

 

 

 

 

 

 

 

 

 

 

 

 

 

#슈퍼코딩, #1:1관리형부트캠프, #백엔드, #backend, #백엔드공부, #개발공부, #백엔드개발자 #취준일기, #취준기록, #취뽀, #빡공, #HTML/CSS, #javascript, #react , #java, #spring