Database에 연결을 해서 메모리상에 존재하던 데이터를 저장해줘야 다시 켰을때 데이터를 보존할 수 있다.
Flask로 만든 웹서버에서 오고가는 데이터 또한 DB에 저장해주지 않으면, Flask를 다시 실행했을 때 데이터가 날아가게되어 처음부터 다시 입력하고 시작하는 등의 불편함이 동반된다.
이런것을 방지하기위해 DB에 연결하는것이고, DB에 연결하는것을 도와주는 도구를 이용해서 Flask에 연결해보자!
Application Factory를 지키면서 DB연결을 하자.
일단 DB에 만들 테이블을 먼저 생성해준다.
# models.usermodel.py
from kokoa import db
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(64), unique=True, nullable=False)
password = db.Column(db.String(200), nullable=False)
def __repr__(self):
return f"User id : {self.id}, User name : {self.username}"
# return f"User id : {self.id}, User name : {self.username}, E-mail : {self.email}"
(DB)모델은 kokoa에서 db를 import한다.
kokoa를 실행시키면 init.py가 실행되므로 init.py에 있는 db를 import한다고 생각하면 된다.
이렇게 테이블이 어떤모양을 갖고있을지 만들었으면 이제 처리해보자
일단 먼저 ORM을 적용시켜줘야한다. init.py 에 migrate부분을 추가해주고!
Table에 추가하기
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
db = SQLAlchemy()
migrate = Migrate()
def create_app(config=None):
app = Flask(__name__)
db.init_app(app)
migrate.init_app(app, db)
from .models import user_model
위와같이 model을 추가해줬으면 이제 shell에서 명령어를 쳐줘야한다.
FLASK_APP=kokoa flask db init
FLASK_APP=kokoa flask db migrate
FLASK_APP=kokoa flask db upgrade
디비를 관리하는 초기파일을 migrations라는 디렉터리에 생성해주고, 이 파일을 알아서 관리해주므로 init을 해준 이후부터 모델에 테이블을 추가하거나 하는등 변화를 줬을땐, migrate와 upgrade만 해주면 된다!
relation table 관리하기!
만약 어떤 테이블이 1:N의 관계를 갖는다고 생각해보자.
지금 여기서는 User테이블이 있는 상태이고, 이 User가 어떤 (1:1)채팅방을 갖고있다고 생각했을때, 한명의 유저는 여러개의 채팅방을 가질 수 있다.
이러한 관계를 만든다고 하면,
class Room(db.Model):
__tablename__ = 'room'
id = db.Column(db.Integer, primary_key = True)
user_id = db.Column(db.Integer(), db.ForeignKey('user.id', ondelete='CASCADE'))
company_id = db.Column(db.Integer(), db.ForeignKey('company.id', ondelete='CASCADE'))
user = db.relationship('User', backref=db.backref('rooms', cascade='all, delete-orphan'))
company = db.relationship('Company', backref=db.backref('rooms', cascade='all, delete-orphan'))
def __repr__(self):
return f"Room id : {self.id}, User - Company : {self.user_id} - {self.company_id}"
위를 보면 id는 기본이고, user_id 는 User테이블에 있는 id를 ForeignKey로 갖는다는것을 볼 수 있다. 여기서! ondelete='CASCADE'는 삭제연동을 의미한다. 이것을 설정해줌으로써 user를 삭제하게되면 자동으로 room까지 삭제되도록 하는것이다.
그리고 밑에 보면 user = db.relationship~부분의 backref를 볼 수 있다.
이는 역참조를 의미하며 user에서 user.rooms를 통해 채팅방을 참조할 수 있다.
일단 여기까지 DB모델을 설정해주는부분을 했으니, DB에 데이터를 추가하는 부분을 작업하자.
main_route.py라는 함수를 통해 url틍 통해 들어는것을 처리하며 이때 데이터를 같이 넘기면서 user를 추가하는 기능을 구현했다.
<!--index.html 부분 -->
<form name='form' id="login-form" method="post">
<input name="username" type="text" required placeholder="Name"/>
<input name = "password" type="text" required placeholder="Password"/>
<input type='submit' value="Log In" onclick="javascript: form.action='/friends/';" />
<input type='submit' value="Sign Up" onclick="javascript: form.action='/signup';"/>
<a href="#">Find Account or Password</a>
</form>
위와같이 Login과 signup을 할 수 있도록 form을 작성해주었다. method는 post로 설정하였다.
이후 받게되는 데이터는 아래와같이 처리되는데,
from flask import Blueprint, render_template, request, flash, session, g, url_for
from kokoa.models.user_model import User, Room
from kokoa import db
bp = Blueprint('main', __name__)
@bp.route('/')
def index():
return render_template('index.html')
@bp.route('/signup/', methods=['GET','POST'])
def signup():
print('signup input : ',request.form)
username=request.form['username']
password=request.form['password']
# form = UserCreateForm()
if request.method=='POST': #form전송이 제대로 되었다면!
#user가 이미 존재하는지 먼저 체크!
user = User.query.filter_by(username=username ).first()
if not user: #유저가 존재하지 않음 -> 생성
user = User(username=username,\
password=generate_password_hash(password))
db.session.add(user)
db.session.commit()
return f'<script> alert("유저 생성 완료. ID : {username}, PASSWORD : {password}"); location.href="/" </script>'
else: #유저가 이미 존재함 -> 뒤로가기
return f'<script> alert("이미 존재하는 user입니다. 다른 이름을 입력하세요"); location.href="/" </script>'
# flash('이미 존재하는 사용자입니다')
# return '이미 존재하는 username입니다.'
return f'<script> alert("오류. 다시 시작하세요"); location.href="/" </script>'
기본화면에서 form 제출을 POST로 받고 그렇게 받은 form에서 username과 password를 받았다.
db를 조회해서 user가 존재한다면 뒤로가기처리와 이미 존재한다는 알림을 띄우고, user가 db에 없다면 user생성을 하고 이를 알린다.
위와같이 user table에 데이터를 추가하는것을 만들었다!