파이썬기초 - 데이터베이스 연동하기

학습 내용

python에서 sqlite 사용하기

  • sqlite 데이터 읽기
import sqlite3

conn = sqlite3.connect('db.sqlite3')
cursor = conn.cursor()
cursor.excute('SELECT * FROM topics')
topics = cursor.fetchall()
print(topics)

  • sqlite 데이터 쓰기
import sqlite3
conn = sqlite3.connect('db.sqlite3')
curor = conn.cursor()
title = input('title? ')
body = input('body? ')
curor.execute('INSERT INTO topics (title, body) VALUES(?, ?)', (title, body))
conn.commit()
conn.close()

  • python3에서 sqlite3 사용하기 (read, write)

flask 앱에 적용하기

  • 전체 코드
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 ...."}
]


def template(content, id=None):
  contextUI = ''
  if id != None:
    contextUI = '<input type="submit" value="delete" class="btn btn-dark">'
  conn = sqlite3.connect('db.sqlite3')
  cs = conn.cursor()
  cs.execute('SELECT * FROM topics')
  topics = cs.fetchall()
  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/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
      <style>
        h1{{
          border-bottom:10px solid green;
        }}
        h1>a{{
          text-decoration:none;
        }}
      </style>
    </head>
    <body class="container">
      <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-dark">create</a>
          {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('db.sqlite3')
  cs = conn.cursor()
  cs.execute('SELECT * FROM topics WHERE id=?', (id,))
  topic = cs.fetchone()
  conn.close()
  title = topic[1]
  body = topic[2]
  return template(f'<h2>{title}</h2>{body}', id)

@app.route('/create/')
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('db.sqlite3')
  cs = conn.cursor()
  cs.execute('INSERT INTO topics (title, body) VALUES(?,?)',(title,body))
  id = cs.lastrowid
  conn.commit()
  conn.close()
  return redirect(f'/read/{id}/')


@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,))
  conn.commit()
  conn.close()
  
  return redirect('/')

app.run()
  • 코드 설명
  1. sqlite로 db 읽어서 리스트 만들기 (read)
# 이 부분을 디비데이터 받아와서 쓰는 것으로 변경할 예정
def template(content, id=None):
  liTags = ''
  for topic in topics:
    liTags = liTags + f'<li><a href="/read/{topic["id"]}/">{topic["title"]}</a></li>'

위의 코드를 아래와 같이 변경

# 아래와 같이 변경
def template(content, id=None):
  conn = sqlite3.connect('db.sqlite3')
  cs = conn.cursor()
  cs.execute('SELECT * FROM topics')
  topics = cs.fetchall()
  conn.close()
  print('topics', topics)
  liTags = ''
  for topic in topics:
    #변경
    liTags = liTags + f'<li><a href="/read/{topic[0]}/">{topic[1]}</a></li>'
  return f'''
  <html>
    <body>
      <h1><a href="/">WEB</a></h1>
      <ol>
        {liTags}
      </ol>
      {content}
      <ul>
        <li><a href="/create/">create</a></li>
        <li>
          <form action="/delete/{id}/" method="POST">
            <input type="submit" value="delete">
          </form>
        </li>
      </ul>
    </body>
  </html>
  '''
  1. read에서 디비데이터 받아와서 화면 변경하기
@app.route('/read/<int:id>/')
def read(id):
  #db에서 데이터 가져와 사용
  conn = sqlite3.connect('db.sqlite3')
  cs = conn.cursor()
  cs.execute('SELECT * FROM topics WHERE id=?', (id,)) #튜플
  topic = cs.fetchone()
  print('topic', topic)
  conn.close()
  title = topic[1]
  body = topic[2]
  return template(f'<h2>{title}</h2>{body}', id)
  1. write 기능 추가 (create_process함수)
@app.route('/create_process/', methods=['POST'])
def create_process():
  # db에 데이터 추가
  #title 값 가져오기
  title = request.form['title']
  #body 값 가져오기
  body = request.form['body']
  conn = sqlite3.connect('db.sqlite3')
  cs = conn.cursor()
  cs.execute('INSERT INTO topics (title, body) VALUES (?,?)',(title, body))
  id = cs.lastrowid
  conn.commit()
  conn.close()
  #id가 있기 때문에 nextId를 쓸 필요가 없다
  return redirect(f'/read/{id}/')  #redirect 사용
  1. 삭제 기능
    아이디를 받아와 삭제
@app.route('/delte/<int:id>', methods=['POST'])
def delete(id):
  conn = sqlite3.connect('db.sqlite3')
  cs = conn.cursor()
  cs.execute('DELETE FROM topics WHERE id = ?',(id,))
  conn.commit()
  conn.close()
  return redirect('/')
  • 부트스트랩 이용
  1. head에 추가
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
  1. template함수에 html 변경
 <html>
    <head>
      <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
      <style>
        h1{{
          border-bottom: 10px solid blue;
        }}
      </style>
    </head>
    <body class='container'>
      <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-success">create</a>
          <input type="submit" value="delete" class="btn btn-danger">
        </div>
      </form>
    </body>
  </html>

학습 후기

어려웠던 부분과 해결

sql문은 이전에 해봤던 것이었는데도 데이터를 가져오고 flask 앱과 연결하면서 어떻게 써야하는지 약간 헷갈렸다. 하지만 glitch로 바로 확인하며 몇번 해보니 금방 익숙해졌다.

소감

2주간의 웹기초와 파이썬 강의가 끝났다.
짧은 시간이였지만 이고잉 강사님께 많은 것을 배웠다.
공부를 하며 스스로를 독려하고 칭찬하는 것이 꾸준히 하는데 큰 자양분이고 계속 할 수 있는 힘인 것을 느낀다.
이런 방식의 수업은 처음이였는데 누군가 문제가 생겼을 때 다 같이 코드리뷰를 하는 것이 이미 문제를 해결한 사람에게도 상대방의 코드에서 문제가 발생한 지점을 찾으며 자신의 지식을 재확인한다는 점에서 좋은 수업과정이였다고 생각한다.

좋은 웹페이지 즐겨찾기