[개발일지 4월 1일] [공통교육-파이썬 기초] 플라스크 앱에 데이터베이스 연동 - 이고잉 강사

박재준·2022년 4월 1일
0

1. 학습한 내용

  • server.py 모든 내용
from flask import Flask, request, redirect
import sqlite3

app = Flask(__name__)

topics = [
  {"id":1, "title":"html", "body":"html is ...."},
  {"id":2, "title":"css", "body":"css is ...."},
  {"id":3, "title":"js", "body":"js is ...."}
]
# nextId = 4


#def read(id)의 return중 id를 받아옴, 그리고 그 id값을 form action의 {id}로 감
def template(content, id=None):
  contextUI = ''
  if id != None:   #만약 id가 None이 아니라면, contextUI가 실행됨
  	#contextUI는 delete 기능을 전송함 / class는 버튼의 디자인
    contextUI = ' <input type="submit" value="delete" class="btn btn-secondary">'
  conn = sqlite3.connect('tt.sqlite3')    #tt.sqlite3 데이터 값을 연결
  cs = conn.cursor()   # conn을 연결하여 cursor를 만드는 것(데이터를 체크하는 것)
  cs.execute('SELECT * FROM topics')   # topics로 부터 selecet 작업
  topics = cs.fetchall()   # topics 변수에다가 모든(all) cs 데이터를 가져옴
  conn.close()
  liTags = ''
  for topic in topics:
    liTags = liTags + f'<li><a href="/read/{topic[0]}/">{topic[1]}</a></li>'
  return f'''
  <html>
    <head>
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
      <style>
        h1{{
          border-bottom:10px solid green;   # h1태그에 초록색 밑줄 10px 굵기로 형성
        }}
      </style>
    </head>  
    <body class="container">  #night값이 나오는 버튼 만들고, 클릭하면 배경은 검은색, 글씨는 흰색으로 변경
      <input type="button" value="night" onclick="
        document.querySelector('body').style.backgroundColor = 'black';   
        document.querySelector('body').style.color = 'white';
      ">
      <h1><a href="/">WEB</a></h1>
      <ol>
        {liTags}
      </ol>
      {content}
      <form action="/delete/{id}/" method="POST" >
      <div class="btn-group" role="group" aria-label="Basic example">
        <a href="/create/" class="btn btn-secondary">create</a></li>
        {contextUI}  
      </div>
      </form>
      
    </body>
  </html>
  '''

@app.route("/")
def index():
  return template('<h2>Welcome</h2>Hello, WEB!')

@app.route("/read/<int:id>/")
def read(id):
  conn = sqlite3.connect('tt.sqlite3')
  cs = conn.cursor()
  cs.execute('SELECT * FROM topics WHERE id=?', (id,))
  topic = cs.fetchone() #아이디 한건을 가져옴
  # print('topic', topic.title, topic.body)
  conn.close()   # 이것을 안하면, 계속 구동되기 때문에, 넣는 것이 중요!
  title = topic[1]  # topic의 두번째 값을 title에 저장
  body = topic[2]	# topic의 세번째 값을 body에 저장
  # for topic in topics :
  #   if topic['id'] == id:
  #     title = topic['title']
  #     body = topic['body']
  #     break;
  return template(f'<h2>{title}</h2>{body}', id)

@app.route('/create/') #create_post로 post방식으로 전송(밑의 creat_process 호출)
def create():
  content = '''
    <form action="/create_process/" method="POST">  
      <p><input type="text" name="title" placeholder="title"></p>
      <p><textarea name="body" placeholder="body"></textarea></p>
      <p><input type="submit" value="create"></p>
    </form>
  '''
  return template(content)

@app.route('/create_process/', methods=['POST'])
def create_process():
  title = request.form['title']
  body = request.form['body']
  conn = sqlite3.connect('tt.sqlite3')  # 위랑 같음
  cs = conn.cursor()  # 위랑 같음
  cs.execute('INSERT INTO topics (title, body) VALUES(?,?)',(title,body))
  # cs.execute의 INSERT 과정을 통해 topics에 title, body값을 추가
  id = cs.lastrowid  
  # lastrowid는 db_cursor를 이용해 excute한 테이블의 마지막 행 id 값을 가져와주는데, 
  # 자기 자신(cursor)이 건든 값만 가져오므로 id를 동시에 만드려는 시도가 있어도 
  # 영향을 받지 않음
  conn.commit()
  conn.close()
  return redirect(f'/read/{id}/')


  # global nextId  # 함수 밖 (전역) 설정
  # title = request.form['title']
  # body = request.form['body']
  # newTopic = {"id": nextId , "title" : title, "body": body}
  # topics.append(newTopic)  #newTopic에 추가한 내용이 topics의 끝에 추가
  # nextId = nextId + 1
  # return redirect(f'/read/{nextId-1}/')  #nextId를 써어 행을 추가했으니까 1이 증가되어있음
  # 우리가 다시 돌아가려는 곳은 nextId 증가되기 전이니까 -1해서 돌아감
  # redirect를 통해서 다시 원래 사이트로 돌아감

  
@app.route('/delete/<int:id>/', methods=['POST'])
def delete(id):
  
  conn = sqlite3.connect('db.sqlite3')
  cs = conn.cursor()
  cs.execute('DELETE FROM topics WHERE id = ?',(id,))  #topics의 해당 id값을 찾아 삭제
  conn.commit()
  conn.close()
  
  return redirect('/')
  
#   for topic in topics:
#     if topic['id'] == id:
#       topics.remove(topic)
#       break;
#   return redirect('/')  #home으로 다시 redirect


# # @app.route('/update/')
# # def update():
# #   return 'Update'

app.run()   #app 실행

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

필기내용

  • form action의 method의
    1) get 방식(디폴트값) : url를 통해 데이터 전송(아주 많은 데이터 전송 X)(read)
    2) post 방식 : url이 아닌 숨겨진 방식으로 데이터 전송(한계가 없음)(write, delete, create)

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

  • 데이터베이스 : 서로 연관된 표를 그룹핑해서 이름을 붙인것

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

<오늘 glitch 내용>

  • terminal → sqlite3(데이터베이스 관리하는 프로그렘) enter → 켜짐
  • .open db.sqlite3 enter ( db.sqlite3이란 파일이 없다면 생성)(앞으로 내리는 명령은 db.sqlite3에 저장)

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

TIP
문법적인 것은 대문자 / 값들은 소문자(저번 필기내용)

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

CREATE TABLE topics (
id INTEGER PRIMARY KEY,                 #PRIMARY KEY(ID와 같은 식별자에 반드시 지정)
title TEXT NOT NULL,
body TEXT
);

→ enter

  • .table → enter → topics 출력

  • .schema topics → enter → topics의 테이블 구조를 출력

  • INSERT INTO topics (title,body) VALUES(‘SQLite’, ‘SQLite is ...’); → enter
    → 데이터 삽입(INSERT INTO 구조) / id는 autoincrement 구조(자동으로 합해짐)

  • 참고 내용 : DROP TABEL topics: #테이블을 없애는 명령문

  • SELECT * FROM topics; → enter #우리가 입력한 데이터가 나옴

= 참고 내용# : DELETE FROM topic WHERE id = 2; 하면 아이디 2가 삭제됨

  • .exit → enter

  • ls –1 → enter : 파일목록 보여줌
    → db.sqlite3에 우리가 만든 파일이 들어가있음

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

import sqlite3
sqlite3.connect('db.sqlite3')
#from sqlite3 import connect
#connect('db.sqlite3') 

도 동일한 방법

= conn.cursor() : conn을 연결하여 cursor를 만드는 것(데이터를 체크하는 것)

  • python3 read.py → enter(읽기 기능)
    → 1, ‘SQLite’, ‘SQLite is ...’ 출력

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

  • create.py 만들기 :
    python3 create.py
    title?에 mysql → enter
    body?에 mysql is ... → enter
    → 데이터가 추가됨!

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

  • body태그 화면 중간으로 하는 기능 (관련 사이트) (예시 : 하단 태그)
    <body class="container">

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

  • TIP
    Glitch 코드 embed this app 기능(다른 블로그의 글에서 glitch 코드를 실행하는 창을 만드는 기능)(태그를 copy후, 다른 블로그에서 붙여넣기 하면 됨)(밑의 그림 참고)

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

  • TIP
    추가내용 : delete 예외 처리(밑의 그림 코드 확인하기)

  • TIP
    밑줄 없애기 (밑의 그림 코드 확인하기)

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

2. 학습한 내용 중 어려웠던 점 또는 해결못한 것들

1) sqlite3 활용하는 법
2) terminal에서 데이터 삽입, 데이터베이스 형성...시 오류들
3) 예전에 사용했던 코드들의 기억 상실...

3. 해결방법 작성

1) 여태했던 sqlite3 수업 처음부터 다시 반복해보기
2) 코딩할 때, 오타를 유의하기, 세미콜론, 콤마, 들여쓰기 등 잘하기
3) 이건 순수 반복하거나, 직접 적어보면서 공부하기

4. 학습 소감

1) 오늘 처음으로 직접 화면 공유를 요청해서 질의응답을 받았다. 식은 땀이 났다.
no module이라고 뜨면서 sqlite3를 import 할 수 없다고 했으며,
이고잉 선생님께서도 가르쳐주면서 db이름을 바꾸시는 작업을 추가적으로 해주셨고...
중간에 뭘 잘 못 누르는건지, 잘 못 타이핑 한건지 모르겠다...
강의 집집중 하기...!

profile
초급 개발자

0개의 댓글