'7.정보관리'의 이전 글들에서 DB의 개념(7.1)과 파이썬 프로그램 안에서 DB를 사용하는 방법(7.2)을 살펴보았다. 포스팅의 주제가 웹 서비스개발 이고 웹 서비스의 가장 중요한 역할이 정보를 관리하는 것이기 때문에 웹 서비스에서 DB를 쓰고(write), 읽는(read) 동작에 대해 살펴보겠다.
DB에 들어있는 책 정보를 웹 페이지를 통해 보여주는 프로젝트를 예제로 살펴보자. 아래 그림과 같이 프로젝트 디렉토리를 만들고 뷰(view)파일들(웹 페이지를 구성할 파일들)을 생성하자.
▶ 07_webpage_DB/static/main.css
웹 페이지에 디자인을 적용하지 않으므로 CSS파일은 비워둔다.
▶ 07_webpage_DB/templates/books.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='main.css')}}">
<title>Registered books</title>
</head>
<body>
<a href="{{url_for('home')}}">Home</a>
{%for book in books%}
<h2>{{book.bookTitle}}</h2>
<p>ISBN: {{book.isbn}}</p>
<p>Pages: {{book.pages}}</p>
<br>
{%endfor%}
</body>
</html>
books.html 파일의 내용은 books라는 파이썬 리스트를 받아서 리스트의 아이템들을 순서대로 탐색하면서 책 제목(book.bookTitle), ISBN(book.isbn), 페이지 수(book.pages)를 페이지에 출력하는 내용으로 구성되어 있다.
▶ 07_webpage_DB/templates/home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='main.css')}}">
<title>Home</title>
</head>
<body>
<a href="{{url_for('showBooks')}}">Show books</a>
</body>
</html>
home.html 파일은 책 정보를 보여주는 페이지로 가는 링크 '<a href="{{url_for('showBooks')}}">Show books</a>' 를 사용자에게 제공한다.
마지막으로 웹 페이지들을 구동시킬 로직(웹 서버)을 아래와 run.py 파일 안에 구성하자.
▶ 07_webpage_DB/run.py
내용이 조금 길어 보이지만 차근 차근 살펴보면 어렵지 않게 기능을 이해할 수 있다. 설명은 코드에 주석(#)으로 달았다.
from flask import Flask, render_template, url_for
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
#### DB를 사용하기 위한 정보들을 설정한다.
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://flaskweb:your_password@localhost:3306/flaskdb'
db = SQLAlchemy(app)
#### 데이터베이스의 table을 클래스 형태로 모델링(정의)한다.
#### (자세한 내용은 '7.2. 파이썬으로 DB 사용하기'를 참조)
class Bookinfo(db.Model):
id = db.Column(db.Integer, primary_key=True)
bookTitle = db.Column(db.String(30), unique=True, nullable=False)
isbn = db.Column(db.String(60), unique=True, nullable=False)
pages = db.Column(db.Integer, unique=False, nullable=False)
db.create_all()
#### db.session.query(Bookinfo).all() 명령은 DB에서 bookinfo table에 있는 내용을 모두(all()) 가져온다.
#### 만약 table에 아무 내용이 없다면(if not) 책 정보를 DB의 bookinfo table에 입력한다.
#### ※ MariaDB의 table 이름은 대소문자 구분이 없기 때문에
#### Bookinfo 클래스가 DB의 bookinfo table에 대응되는 것을 7.2절에서 살펴보았다.
if not db.session.query(Bookinfo).all():
books = []
books.append(Bookinfo(bookTitle = '논어', isbn = '9788952204639', pages = 374))
books.append(Bookinfo(bookTitle = '맹자-상', isbn = '9788982641237', pages = 432))
books.append(Bookinfo(bookTitle = '맹자-하', isbn = '9788982641244', pages = 464))
books.append(Bookinfo(bookTitle = '대학', isbn = '9788982644054', pages = 416))
for book in books:
db.session.add(book)
db.session.commit()
else:
pass
#### URL의 / 또는 /home 위치로 접근했을 때 호출되는 함수다.
#### 웹 서비스의 메인 페이지를 사용자에게 보여준다.
@app.route("/")
@app.route("/home")
def home():
return render_template("home.html")
#### 사용자가 책 정보 조회 페이지(/books)로 접근했을 때 책 정보 페이지를 보여주는 로직을 기술한 함수다.
#### Bookinfo 클래스에 대응되는 DB table의 내용을 모두 가져와서(db.session.query(Bookinfo).all())
#### 해당 정보를 books.html 웹 페이지를 통해 사용자에게 보여준다.
@app.route("/books")
def showBooks():
bookList = db.session.query(Bookinfo).all()
return render_template("books.html", books = bookList)
if __name__ == '__main__':
app.run("127.0.0.1", 5000)
run.py 스크립트 구성을 마쳤으면 파이참의 경우 run.py 파일 위에 마우스 커서를 위치시키고 오른쪽 마우스 버튼을 클릭해서 프로젝트를 실행시키자.
웹 브라우저를 실행시키고 주소창에 127.0.0.1:5000을 입력해서 웹 서버에 접속하면 먼저 홈(home)화면을 볼 수 있다.
'Show books' 링크를 클릭해서 책 정보 페이지로 이동하면 DB에 저장되어 있는 책 정보를 웹 페이지를 통해 볼 수 있다.
참고로 DB에 입력되어 있는 데이터를 고치는(update) 명령은 아래와 같이 할 수 있다.
#### isbn 필드 값을 이용해 DB에서 아이템을 읽어왔다.
abook = Bookinfo.query.filter_by(isbn = 'an ISBN').first()
#### 새 값을 설정한다.
abook.bookTitle = 'new title'
#### db에 내용을 반영한다.
db.session.commit()
이번 예제를 통해서 파이썬 스크립트를 이용해서 DB를 다루는(쓰고 읽는) 방법을 살펴보았다. 예제가 길지 않으니 시간을 가지고 차분히 따라서 진행해 보면 그 흐름과 내용을 이해할 수 있을 것이다.
■
'파이썬 웹 프로그래밍 기본' 카테고리의 다른 글
7. 정보관리 - 7.2.파이썬으로 DB 사용하기 (0) | 2020.09.01 |
---|---|
7. 정보 관리 - 7.1.데이터베이스(DB) (0) | 2020.08.31 |
6. 패키지 - 6.2. 플라스크 프로젝트의 구조화 (0) | 2020.08.27 |
6. 패키지 - 6.1. 개념 소개 (0) | 2020.08.25 |
5. 입력 처리 - 5.3. Flask WTF를 이용한 입력처리 프로젝트 (0) | 2020.08.21 |
댓글