1. 데이터 베이스 구축에 앞서 생각해보기
이제 데이터 베이스를 구축한다.
데이터 베이스에 들어갈 테이블과 속성들 나열해 본다.
- 유저 - 유저 이름, 암호화된 비번
- 작성글 - 육각남 찾기 작성한 내용 관련 데이터, 작성자
- 리플 - 리플 내용, 작성자
각각의 테이블에는 유니크한 데이터베이스 ID가 포함된다.
유저-작성글-리플은 서로 참조하여 검색에 활용할수 있도록 기능 구현해본다.
다음으로는 통계관련 테이블이다.
- 키 - 나이별
- 학력 - sky, 인서울, 지방 거점대학
- 나이 - 연령별, 지역별
- 직업 - 대기업, 공기업, 공무원, 중견, 그외, 지역별
- 종교 - 천주교, 기독교, 불교, 무교
- 거주지 - 지역별
통계 관련 테이블은 실제 통계 내용을 살펴보고 그 속성을 추가하는게 나아 보인다.
2. 데이터 베이스 구축 기본
2-02 모델로 데이터베이스 관리하기 - 점프 투 FastAPI (wikidocs.net)
2-02 모델로 데이터베이스 관리하기
* `[완성 소스]` : [https://github.com/pahkey/fastapi-book/tree/v2.02](https://github.com/pahkey/fastapi…
wikidocs.net
참고하였다.
pip3 install sqlalchey
설치하고 요구사항.txt 파일에 추가한다.
#database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./haxagonMan.db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
database.py를 생성하고 위의 코드를 추가한다.
SessionLocal은 데이터베이스에 접속하기 위해 필요한 클래스
create_engine, sessionmaker 등을 사용하는것은 SQLAlchemy 데이터베이스를 사용하기 위해 따라야 할 규칙이다.
autocommit=False 일종의 자동저장 옵션으로 False는 commit 실행이 있어야 저장된다. True로 해버리면 데이터를 잘못 저장했을때 rollback을 할수 없다는 점을 주의한다.
create_engine은 데이터 베이스에 접속하는 세션수를 제어하고, 또 세션 접속에 소요되는 시간을 줄이고자 하는 용도로 사용한다.
declarative_base 함수에 의해 반환된 Base 클래스는 데이터베이스 모델을 구성할 때 사용되는 클래스이다.
3. 데이터베이스 모델링
models.py 파일을 생성하고 코드를 추가한다.
# models.py
from database import Base
from sqlalchemy import Column, Integer, String, DateTime, ARRAY, ForeignKey
from sqlalchemy.orm import relationship
class DbUser(Base):
__tablename__= 'user'
id = Column(Integer, primary_key=True, index=True)
username = Column(String)
password = Column(String)
items = relationship('DbPost', back_populates='user')
# todo 암호 관련 작업이 필요하다.
class DbPost(Base):
__tablename__ = 'post'
id = Column(Integer, primary_key=True, index=True)
age = Column(ARRAY(Integer))
height = Column(ARRAY(Integer))
education = Column(ARRAY(String))
occupation = Column(ARRAY(Integer))
residence_location = Column(ARRAY(Integer))
religion = Column(ARRAY(Integer))
timestamp = Column(DateTime)
user_id = Column(Integer, ForeignKey('user.id'))
user = relationship('DbUser', back_populates='items')
comments = relationship('DbComment', back_populates='post')
class DbComment(Base):
__tablename__ = 'comment'
id = Column(Integer, primary_key=True, index=True)
text = Column(String)
username = Column(String)
timestamp = Column(DateTime)
post_id = Column(Integer, ForeignKey('post.id'))
post = relationship('DbPost', back_populates='comments')
패스워드는 아직 암호화 되지 않고 그대로 받았기 때문에 추가 작업이 필요하다.
Dbuser 클래스는 고우 id, 유저명, 암호가 들어왔다.
중요한 점은 DbPost인데 위에 언급한 속성을 리스트로 받을 있게 하였다.
실제로 나이는 20~30대, 키는 175 이상, 학력은 sky~인서울과 같이 복수 응답이 가능해야 하기 때문이다.
4. 데이터 베이스 생성
데이터 베이스 생성에는 alembic을 이용한다. 요구사항.txt에 추가한다.
터미널에서 실행한다.
pip install alembic
alembic init migrations
초기화
alenbic.ini 파일에
(... 생략 ...)
sqlalchemy.url = sqlite:///./hexagonMan.db
(... 생략 ...)
migrations-vsrsions-env.py 파일에
import models
추가하고
target_metadata = mymodel.Base.metadata
수정한다.
alembic revision --autogenerate
리비전 파일을 생성하고
alembic upgrade head
업데이트하면 데이터베이스 파일이 생성된다.
앞으로 모델 파일이 업데이트가 있을때마다 리비전 파일을 생성하고 업데이트를 하면 내용이 반영된다.
# models.py
from database import Base
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey
from sqlalchemy.orm import relationship
class DbUser(Base):
__tablename__= 'user'
id = Column(Integer, primary_key=True, index=True)
username = Column(String)
password = Column(String)
items = relationship('DbPost', back_populates='user')
# todo 암호 관련 작업이 필요하다.
class DbPost(Base):
__tablename__ = 'post'
id = Column(Integer, primary_key=True, index=True)
age = Column(String)
height = Column(String)
education = Column(String)
occupation = Column(String)
residence_location = Column(String)
religion = Column(String)
timestamp = Column(DateTime)
user_id = Column(Integer, ForeignKey('user.id'))
user = relationship('DbUser', back_populates='items')
comments = relationship('DbComment', back_populates='post')
class DbComment(Base):
__tablename__ = 'comment'
id = Column(Integer, primary_key=True, index=True)
text = Column(String)
username = Column(String)
timestamp = Column(DateTime)
post_id = Column(Integer, ForeignKey('post.id'))
post = relationship('DbPost', back_populates='comments')
문제가 발생했다.
sqlite는 ARRAY형식으로 데이터를 저장하지 못하기 때문에 Column(String)으로 변경할수 밖에 없었다.
문자열을 파싱하는 방법으로 처리할수 밖에 없을 듯하다.
tableplus를 통해서 생성된 db 파일을 살펴보면 문제없이 데이터베이스가 생성된 것을 확인할수 있다.