📝 RDB
데이터베이스(DataBase)의 종류는 크게 1. 관계형 데이터베이스(RDB, 2. NoSQL(Not Only SQL)로 나뉜다.
RDB(Relation Database)는 관계형 데이터 모델을 기반으로 한 데이터 베이스다.
다시 말해, 키(Key) - 값(Value)들의 간단한 관계를 테이블화한 데이터베이스다. RDB는 다음 특징을 가진다.
- 데이터 독립성이 높다.
- 고수준의 DML을 사용해서, 결합, 제양, 투영 등의 관계 조작에 의해 비약적으로 표현 능력을 높일 수 있다.
- 이들의 관계 조작에 의해 자유롭게 구조를 변경할 수 있다.
💡 RDB의 종류
- Oracle
- MySQL
- MS-SQL
- DB2
- Maria DB
- Derby
- SQLite
📝 RDB와 Flask의 상호작용
Flask에서 RDB를 연동하면 어떻게 될까 ? Flask에서 입력 받은 내용들을 DB에 저장할 수 있어야 한다.
= 효율적인 데이터 관리 기능 제공
파이썬은 오픈 소스와 상용 데이터베이스에 대한 대부분의 데이터베이스 엔진을 위한 패키지를 가지고 있다.
앞으로의 포스팅에서는 그 중, sqlite3 와 Flask 어플리케이션 안에 있는 SQLAlchemy를 사용해서 진행한다.
SQLAlchemy는 파이썬 코드에 DB와 연결하기 위해 사용되는 라이브러리다.

📝 Flask - RDB 예제 : 게시판 구현하기
💡 DB 사용자 추가
from flask import Flask, render_template, request, url_for, redirect import sqlite3 # salite3 app = Flask(__name__) conn = sqlite3.connect("database.db") # splite3 db 연결 print("Opened database successfully") conn.execute("CREATE TABLE IF NOT EXISTS Board(name TEXT, context TEXT)") # Board 라는 DB생성 print("TABLE Created Successfully") name = [ ["Elice", 15], ["Dodo", 16], ["checher", 17], ["Queen", 18] ] for i in range(len(name)): conn.execute(f"INSERT INTO Board(name,context) VALUES('{name[i][0]}', '{name[i][1]}')") # Board DB에 데이터 삽입 conn.commit() # 지금껏 작성한 SQL, DB에 반영 commit conn.close() # 작성 다한 DB는 닫아줘야함 close # ================= 여기서부터는 다시 Flask 영역 ========================== @app.route('/') def board(): con = sqlite3.connect("database.db") cur = con.cursor() cur.execute("SELECT * FROM Board") rows = cur.fetchall() print("DB: ") for i in range(len(rows)): print(rows[i][0] + ':' + rows[i][1]) return render_template("board1.html", rows = rows) @app.route("/search", methods=["GET","POST"]) def search(): if request.method == "POST": name = request.form["name"] # search.html 가보면, form에 name만 받기로 함. con = sqlite3.connect("database.db") cur = con.cursor() cur.execute(f"SELECT * FROM Board WHERE name='{name}'") rows = cur.fetchall() print("DB : ") for i in range(len(rows)): print(rows[i][0] + ':' + rows[i][1]) return render_template("search.html", rows=rows) else: return render_template("search.html") @app.route("/add", methods=["GET","POST"]) def add(): if request.method == "POST": try: name = request.form["name"] context = request.form["context"] # DB에 접근해서, 데이터를 삽입할때는, 직접 DB를 열어야되는데, 윗 과정처럼, close까지 하기 힘드니깐, 하는 방식, 결과는 같은 것 ! with sqlite3.connect("database.db") as con: cur = con.cursor() cur.execute(f"INSERT INTO Board(name,context) VALUES('{name}','{context}')") con.commit() except: con.rollback() # DB 롤백함수, SQL이 오류나면, 반영전, 이전 상태로 돌리는 것 finally: return redirect(url_for("board")) else: return render_template("add.html") if __name__ == '__main__': app.run()
<!-- ./templates/board1.html --> <!doctype html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>SQLite3 게시판 등록</title> <style type="text/css"> body { text-align: center; } </style> </head> <body> <h3>게시판</h3> <h4><a href="{{url_for('add')}}">추가</a> <a href="{{url_for('search')}}">검색</a><br><br>목록</h4> <table border=1 width="600" align="center"> <thead> <td>이름</td> <td>내용</td> </thead> {% for row in rows %} <tr> <td>{{ row[0] }}</td> <td>{{ row[1] }}</td> </tr> {% endfor %} </table> </body> </html>
<!-- ./templates/add.html --> <!doctype html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>SQLite3 게시판 등록</title> <style type="text/css"> body { text-align: center; } </style> </head> <body> <h3>게시판</h3> <h4>추가</h4> <form action="/add" method="POST"> 이름<br> <input type="text" name="name" /><br> 내용<br> <input type="text" name="context" style="text-align:center; width:400px; height:100px;" /><br><br> <input type="submit" value="게 시" /><br> </form> </body> </html>
<!-- ./templates/search.html --> <!doctype html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>SQLite3 게시판 등록</title> <style type="text/css"> body { text-align: center; } </style> </head> <body> <form action="/search" method="POST"> <input type="text" name="name" /> <input type="submit" value="검 색" /><br> </form> <h4>검색결과</h4> {% if rows%} <table border=1 width="600" align="center"> <thead> <td>이름</td> <td>내용</td> </thead> {% for row in rows %} <tr> <td>{{ row[0] }}</td> <td>{{ row[1] }}</td> </tr> {% endfor %} {% else %} <p> 검색결과가 없습니다. </p> {% endif %} </table> </body> </html>

💡 중복 사용자 제어 ( 위에, DB 사용자 추가에서 변한 코드는 몇 없음
from flask import Flask, render_template, request, url_for, redirect import sqlite3 # salite3 app = Flask(__name__) conn = sqlite3.connect("database.db") # splite3 db 연결 print("Opened database successfully") conn.execute("CREATE TABLE IF NOT EXISTS Board(name TEXT, context TEXT)") # Board 라는 DB생성 print("TABLE Created Successfully") name = [ ["Elice", 15], ["Dodo", 16], ["checher", 17], ["Queen", 18] ] for i in range(len(name)): conn.execute(f"INSERT INTO Board(name,context) VALUES('{name[i][0]}', '{name[i][1]}')") # Board DB에 데이터 삽입 conn.commit() # 지금껏 작성한 SQL, DB에 반영 commit conn.close() # 작성 다한 DB는 닫아줘야함 close # ================= 여기서부터는 다시 Flask 영역 ========================== @app.route('/') def board(): con = sqlite3.connect("database.db") cur = con.cursor() cur.execute("SELECT * FROM Board") rows = cur.fetchall() print("DB: ") for i in range(len(rows)): print(rows[i][0] + ':' + rows[i][1]) return render_template("board1.html", rows = rows) @app.route("/search", methods=["GET","POST"]) def search(): if request.method == "POST": name = request.form["name"] # search.html 가보면, form에 name만 받기로 함. con = sqlite3.connect("database.db") cur = con.cursor() cur.execute(f"SELECT * FROM Board WHERE name='{name}'") rows = cur.fetchall() print("DB : ") for i in range(len(rows)): print(rows[i][0] + ':' + rows[i][1]) return render_template("search.html", rows=rows) else: return render_template("search.html", msg ="검색어를 입력해주세요.") @app.route("/add", methods=["GET","POST"]) def add(): if request.method == "POST": name = request.form["name"] context = request.form["context"] # DB에 접근해서, 데이터를 삽입할때는, 직접 DB를 열어야되는데, 윗 과정처럼, close까지 하기 힘드니깐, 하는 방식, 결과는 같은 것 ! with sqlite3.connect("database.db") as con: cur = con.cursor() cur.execute(f"SELECT count(*) FROM Board WHERE name='{name}'") # 회원 한명, 추가할라 했는데, 그전에 들어온, name값이랑 같은 이름이 DB에 있으면, 중복회원자이므로, 못하게 제어함 if cur.fetchall()[0][0] == 0: # 중복이름이 없으면 cur.execute(f"INSERT INTO Board(name,context) VALUES('{name}','{context}')") con.commit() cur.execute("SELECT * FROM Board") rows = cur.fetchall() return render_template("board1.html",rows= rows) else: # 중복이름이 있으면 return render_template("add.html",msg = "중복사용자가 있습니다.") else: return render_template("add.html") if __name__ == '__main__': app.run()
<!-- ./templates/board1.html --> <!doctype html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>SQLite3 게시판 등록</title> <style type="text/css"> body { text-align: center; } </style> </head> <body> <h3>게시판</h3> <h4><a href="{{url_for('add')}}">추가</a> <a href="{{url_for('search')}}">검색</a><br><br>목록</h4> <table border=1 width="600" align="center"> <thead> <td>이름</td> <td>내용</td> </thead> {% for row in rows %} <tr> <td>{{ row[0] }}</td> <td>{{ row[1] }}</td> </tr> {% endfor %} </table> </body> </html>
<!-- ./templates/add.html --> <!doctype html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>SQLite3 게시판 등록</title> <style type="text/css"> body { text-align: center; } </style> </head> <body> <h3>게시판</h3> <h4>추가</h4> <form action="/add" method="POST"> 이름<br> <input type="text" name="name" /><br> 내용<br> <input type="text" name="context" style="text-align:center; width:400px; height:100px;" /><br><br> <input type="submit" value="게 시" /><br> </form> {% if msg %} <p> {{ msg }} </p> {% endif %} </body> </html>
<!-- ./templates/reaserch.html --> <!doctype html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>SQLite3 게시판 등록</title> <style type="text/css"> body { text-align: center; } </style> </head> <body> <form action="/search" method="POST"> <input type="text" name="name" /> <input type="submit" value="검 색" /><br> </form> <h4>검색결과</h4> {% if rows%} <table border=1 width="600" align="center"> <thead> <td>이름</td> <td>내용</td> </thead> {% for row in rows %} <tr> <td>{{ row[0] }}</td> <td>{{ row[1] }}</td> </tr> {% endfor %} {% elif msg %} <p> {{ msg }} </p> {% else %} <p> 검색결과가 없습니다. </p> {% endif %} </table> </body> </html>

💡 게시판 내용 생성 및 조회
위에서, DB 사용자 생성, 중복제거 내용과 동일
💡 게시판 내용 수정 및 삭제
#DATABASE from flask import Flask, render_template, request, url_for, redirect import sqlite3 app = Flask(__name__) conn = sqlite3.connect('database.db') print ("Opened database successfully") conn.execute("DROP TABLE IF EXISTS Board") # Board 테이블이 기존에 있다면 삭제 (매번, 동일한 파일에서 실행하면, 내용이 겹쳐서 만듦) conn.execute('CREATE TABLE IF NOT EXISTS Board (name TEXT, context TEXT)') # Board 테이블이 기존에 없다면 생성 print ("Table created successfully") name = [['Elice', 15], ['Dodo', 16], ['Checher', 17], ['Queen', 18]] for i in range(4): conn.execute(f"INSERT INTO Board(name, context) VALUES('{name[i][0]}', '{name[i][1]}')") conn.commit() conn.close() # root = home @app.route('/') def board(): con = sqlite3.connect("database.db") cur = con.cursor() cur.execute("select * from Board") rows = cur.fetchall() print("DB:") for i in range(len(rows)): print(rows[i][0] + ':' + rows[i][1]) return render_template('board1.html', rows = rows) # 게시물 조회 (Read) @app.route('/search', methods = ['GET', 'POST']) def search(): if request.method == 'POST': name = request.form['name'] con = sqlite3.connect("database.db") cur = con.cursor() cur.execute(f"SELECT * FROM Board WHERE name='{name}' or context='{name}'") rows = cur.fetchall() print("DB:") for i in range(len(rows)): print(rows[i][0] + ':' + rows[i][1]) return render_template('search.html', rows = rows) else: return render_template('search.html') # 게시물 생성 (Create) @app.route('/add', methods = ['GET', 'POST']) def add(): if request.method == 'POST': try: name = request.form['name'] context = request.form['context'] with sqlite3.connect("database.db") as con: cur = con.cursor() cur.execute(f"INSERT INTO Board (name, context) VALUES ('{name}', '{context}')") con.commit() except: con.rollback() finally : con.close() return redirect(url_for('board')) else: return render_template('add.html') # 위에 조회, 생성은 이전과 동일 # 게시물 내용 갱신(Update) @app.route("/update/<uid>", methods=["GET","POST"]) def update(uid): if request.method == "POST": name = request.form["name"] context = request.form["context"] # 내용 갱신하고 with sqlite3.connect("database.db") as con: cur = con.cursor() # connection한 db에 접근하기 위해, cursor 객체 만들기 cur.execute(f"UPDATE Board SET name='{name}', context='{context}' WHERE name='{uid}'") con.commit() return redirect(url_for("board")) # 갱신되었는지, board함수 리다이렉트해서, / 페이지 렌더링 else: con = sqlite3.connect("database.db") cur = con.cursor() cur.execute(f"SELECT * FROM Board WHERE name='{uid}'") row = cur.fetchall() return render_template("update.html",row=row) @app.route("/delete/<uid>") def delete(uid): # 들어온 uid 값이랑 name이랑 delete 연산하고 반영 with sqlite3.connect("database.db") as con: cur = con.cursor() cur.execute(f"DELETE FROM Board WHERE name='{uid}'") con.commit() return redirect(url_for('board')) # 삭제 반영하고, 반영됬는지, board함수 리다이렉트, / 페이지 렌더링 if __name__ == '__main__': app.run()
<!-- ./templates/board1.html --> <!doctype html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>SQLite3 게시판 등록</title> <style type="text/css"> body { text-align: center; } </style> </head> <body> <h3>게시판</h3> <h4><a href="{{url_for('add')}}">추가</a> <a href="{{url_for('search')}}">검색</a><br><br>목록</h4> <table border=1 width="600" align="center"> <thead> <td>이름</td> <td>내용</td> <td>수정/삭제</td> </thead> {% for row in rows %} <tr> <td>{{ row[0] }}</td> <td>{{ row[1] }}</td> <td><a href="{{url_for('update', uid = row[0])}}">수정</a> <a href="{{url_for('delete', uid = row[0])}}">삭제</a></td> </tr> {% endfor %} </table> </body> </html>
<!-- ./templates/add.html --> <!doctype html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>SQLite3 게시판 등록</title> <style type="text/css"> body { text-align: center; } </style> </head> <body> <h3>게시판</h3> <h4>추가</h4> <form action="/add" method="POST"> 이름<br> <input type="text" name="name" /><br> 내용<br> <input type="text" name="context" style="text-align:center; width:400px; height:100px;" /><br><br> <input type="submit" value="게 시" /><br> </form> </body> </html>
<!-- ./templates/research.html --> <!doctype html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>SQLite3 게시판 등록</title> <style type="text/css"> body { text-align: center; } </style> </head> <body> <form action="/search" method="POST"> <input type="text" name="name" /> <input type="submit" value="검 색" /><br> </form> <h4>검색결과</h4> {% if rows%} <table border=1 width="600" align="center"> <thead> <td>이름</td> <td>내용</td> </thead> {% for row in rows %} <tr> <td>{{ row[0] }}</td> <td>{{ row[1] }}</td> </tr> {% endfor %} {% else %} <p> 검색결과가 없습니다. </p> {% endif %} </table> </body> </html>
<!-- ./templates/update.html --> <!doctype html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>SQLite3 게시판 등록</title> <style type="text/css"> body { text-align: center; } </style> </head> <body> <h3>게시판</h3> <h4>수정</h4> <form action="" method="POST"> 이름<br> <input type="text" name="name" /><br> 내용<br> <input type="text" name="context" style="text-align:center; width:400px; height:100px;" /><br><br> <input type="submit" value="수 정" /><br> </form> <h4>기존</h4> <table border=1 width="600" align="center"> <thead> <td>이름</td> <td>내용</td> </thead> <tr> <td>{{ row[0][0] }}</td> <td>{{ row[0][1] }}</td> </tr> </table> </body> </html>

728x90
반응형
'python' 카테고리의 다른 글
[Flask] (7) REST API (0) | 2021.01.28 |
---|---|
[Flask] (6) ORM & SQLAlchemy (0) | 2021.01.28 |
[Flask] (4) 인증 & 로그인구현 & 로깅 (0) | 2021.01.25 |
[Flask] (3) 렌더링 템플릿 & Jinja2 & 간단한 게시판 (0) | 2021.01.24 |
[Flask] (2) REST & HTTP Method & API/End Point (0) | 2021.01.22 |