📝 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 |