본문 바로가기
슈퍼코딩 부트캠프/week2

2024.07.05(금) 슈퍼코딩 부트캠프 신입연수원 week2 Day5 일일보고

by zldn 2024. 7. 6.

<To-Do List>

- 54강 ~ 57강 강의듣기

- 일일보고 작성하기

 

<오늘 내운 내용 요약>

54~55강 실습하기 - 게시글을 서버에  저장하려면? POST!

 

>> SQLite란?

- 파일 기반의 RDB로 조금 가볍고 쉬워서 이 언어로 실습해볼것이다.

 

>> BLOB란?

- 이진 대상을 의미하는 Binary Large Object

- 텍스트나 숫자 같은 일반적인 데이터 타입과 달리 이미지, 오디오, 비디오 등과 같은 데이터를 저장하기 위한 타입

 

>> 궁극적으로 글쓰기 페이지를 만들건데  Form 태그와 POST API를 이용해 이미지 등의 정보 서버에 저장하기를 할 것 !

 

1. 당근마켓클론에서 작성했던 글쓰기 버튼을 누르면 글쓰기 페이지로 이동

- 글쓰기에 대해서 a 태그를 쓰면 하이퍼링크 걸고 특정 태그로 이동됨

<a class="write-button" href="write.html">+ 글쓰기</a>

 

2. write.html에서 form, input, button 등을 사용해서 간단히 html 작성

- 다음과 같이 이미지, 제목, 가격, 설명, 장소에 대해서 작성

<form id="write-form">
      <div>
        <label for="image">이미지</label>
        <input type="file" id="image" name="image" />
	  </div>
<form/>
<div>
    <button type="submit">작성 완료</button>
</div>

 

3. write.js 연결해서 submit 발생 시 FormData를 담은 Post 요청을 서버에 보내기

const form = document.getElementById("write-form");

const handleSubmitForm = async (event) => {
  event.preventDefault();
  const res = await fetch("/items", {
    method: "POST",
    body: new FormData(form),
  });
};

form.addEventListener("submit", handleSubmitForm);

 

4. .py(서버)에서 POST 받았을 때에 대해 함수를 작성하고 sql 써서 db에 정보 전달하기

con = sqlite3.connect('db.db', check_same_thread=False)
cur = con.cursor()
@app.post("/items")
async def create_item(image:UploadFile, 
                title:Annotated[str,Form()], 
                price:Annotated[int,Form()], 
                descrition:Annotated[str,Form()], 
                place:Annotated[str,Form()]):
    
    image_bytes = await image.read()
    #이미지는 용량이 크니까 좀 기다려주기
    cur.execute(f"""
                INSERT INTO items (title, image, price, descrition, place)
                VALUES('{title}','{image_bytes.hex()}',{price},'{descrition}','{place}')
                """)
                #INSERT INTO를 통해 items라는 테이블에 VALUES들을 넣어줄 것이다 라는 의미
    con.commit()
    #sql 써서 db에 정보 전달하기
    return "200"

 

* db에 정보가 전달되어 dbeaver에 작성된 모습을 확인할 수 있다.

db

 

5. .js에서 제출 완료되면 다시 원래 페이지로 돌아가기까지 기능 구현

 

- if, else 사용했을 때

const data = await res.json();
  if (data === "200") window.location.pathname = "/";
  else console.error("이미지 업로드에 실패했습니다.");

 

-try, catch 사용했을 때

try {
    const res = await fetch("/items", {
      method: "POST",
      body: new FormData(form),
    });
    const data = await res.json();
    if (data === "200") window.location.pathname = "/";
  } catch (e) {
    console.error("이미지 업로드에 실패했습니다.", e);
  }

 

56 ~ 57강 실습하기 - 저장된 게시글을 확인하려면? GET!

>> 이전에 작성했던 db에 시간칼럼을 추가하기

 

1. db 수정하는 방법

- 이전까지 작성했던 db에는 시간정보가 있지 않아서 이를 추가해서 테이블을 만들고자 한다.

- 이때 db script에서 다음을 작성하고 실행하면 작성했던 테이블이 전부 없어진다. 그 이후 다시 테이블을 작성하면 된다.

DROP TABLE items

 

2. write.js 에서 정보를 보낼때 new Date().getTime()시간 정보도 포함해서 보내도록 수정하기

 

- 다음과 같이 body에 원래 FormData를 담아두고 여기에 추가로 시간정보를 body에 넣어주기

  const body = new FormData(form);
  body.append("insertAt", new Date().getTime()); //시간에 대해서 넣어주기

 

- 또한 그렇게 정의한 body를 POST 메소드로 서버로 전송하도록 수정

const res = await fetch("/items", {
      method: "POST",
      body: body,
    });

 

 

>> 이제 submit이 일어나면 그 정보들을 이전화면인 index.html에 표시될 수 있도록 하기

 

1. index.js에서 get을 이용해 서버에서 정보를 불러오는 함수를 작성한다.

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

fetchList();

 

2. .py(서버)에서 get 요청을 받으면 db에 있는 데이터를 칼럼명과 그에따른 데이터 값을 반환하도록 한다.

@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))
    #위에서 컬럼명도 함께 받았는데 dict(row) for row in rows 이걸해주면 그 데이터들이 dictionary로 정리가 됨

 

3. 이제 반환받은 값을 renderData()를 통해 화면에 띄우도록 한다.

 

- 다음과 같이 data 값을 renderData()의 인자로 주고 함수를 호출한다.

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

 

*console.log를 통해 출력을 했더니 검사에서 console을 확인하니 다음과 같이 배열형태로 data가 전달된 것을 볼 수 있다.

데이터 배열

 

- 자바스크립트 내에서 html에 div를 추가하며 화면을 구성한다.

const renderData = (data) => {
  // data = [{id:1,title:'aa'...},{id:2,title:'bbb'...}..]이런형태
  const main = document.querySelector("main");
  data.forEach((obj) => {
    const div = document.createElement("div");
    div.innerText = obj.title;
    main.appendChild(div);
  });
};

 

<과제>

>> JOIN에 대해 알아보고 벤다이어그램으로 정리하기

JOIN

<하루를 돌아보며>

>> SQL

어제까지만 해도 SQL을 작성하는 게 하나도 이해가 안되고 이게 뭐지 싶었는데 막상 또 강의를 들으며 코딩을 들으니 조금씩 어떻게 적용되는지를 알게 된 것 같다.

그리고 데이터베이스라는 것이 처음 배워봐서 뭐 하나 건들기도 너무 조심스럽고 강의랑 조금만 다르게 나와도 너무 막막하기도 했다.

 

>> 문제가 생겼던 부분

프론트, 백, 서버까지 모든 부분을 왔다갔다 하면서 진행하고 있는데 변수명을 정확히 일치시켜야 한다는 것을 또 깨달았다.

자꾸만 db에 저장한 칼럼명과 서버에서 파이썬으로 작성할때 변수명을 철자 한개씩 틀리게 설정해서 몇번을 해맸다.

결국은 모두 변수명 문제였다. 이런 부분은 좀 더 조심하고 또 유의해서 작성해야겠다.