회원가입, 로그인, 로그아웃 기능이 완성되어 질문, 답변을 "누가" 작성했는지 알 수 있게 되었다. 이제 기능을 조금씩 다듬어서 파이보를 완벽하게 만들어 보자. 여기서는 Question, Answer 모델을 수정하여 "글쓴이"에 해당하는 user 속성을 추가할 것이다.
SQLite 데이터베이스는 ORM을 사용할 때 몇 가지 문제점이 있다. 이것은 SQLite 데이터베이스에만 해당하고 PostgreSQL이나 MySQL 등의 다른 데이터베이스와는 상관없는 내용이다. 앞으로의 진행을 원활하게 하기 위해 SQLite가 발생시킬 수 있는 오류를 먼저 해결하고 넘어가자.
[파일명: projects/myapi/database.py]
from sqlalchemy import create_engine, MetaData
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
(... 생략 ...)
Base = declarative_base()
naming_convention = {
"ix": 'ix_%(column_0_label)s',
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(column_0_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s"
}
Base.metadata = MetaData(naming_convention=naming_convention)
(... 생략 ...)
MetaData 클래스를 사용하여 데이터베이스의 프라이머리 키, 유니크 키, 인덱스 키 등의 이름 규칙을 새롭게 정의했다. 데이터베이스에서 디폴트 값으로 명명되던 프라이머리 키, 유니크 키 등의 제약조건 이름을 수동으로 설정한 것
그리고 migrations 디렉터리의 env.py 파일도 다음과 같이 수정해야 한다.
[파일명: projects/myapi/migrations/env.py]
(... 생략 ...)
def run_migrations_offline() -> None:
(... 생략 ...)
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
render_as_batch=True,
)
(... 생략 ...)
def run_migrations_online() -> None:
(... 생략 ...)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
render_as_batch=True,
)
(... 생략 ...)
ontext.configure 설정에 render_as_batch=True
설정을 추가했다.
이와 같이 수정한 후에 alembic revision --autogenerate
명령과 alembic upgrade head
명령으로
데이터베이스를 변경해야 한다.
(myapi) c:/projects/myapi> alembic revision --autogenerate
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected added unique constraint 'uq_user_email' on '['email']'
INFO [alembic.autogenerate.compare] Detected added unique constraint 'uq_user_username' on '['username']'
Generating /Users/pahkey/projects/myapi/migrations/versions/f77ce8f209c6_.py ... done
(myapi) c:/projects/myapi> alembic upgrade head
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade 87416c9d163d -> f77ce8f209c6, empty message
혹시 이 과정에서 오류가 발생할 경우에는 alembic stamp head
명령을 실행한 후에 다시 위의 과정을 반복
다음과 같이 글쓴이 정보를 Question 모델에 추가하기 위해 user_id, user 속성을 추가
[파일명: projects/myapi/models.py]
(... 생략 ...)
class Question(Base):
__tablename__ = "question"
id = Column(Integer, primary_key=True)
subject = Column(String, nullable=False)
content = Column(Text, nullable=False)
create_date = Column(DateTime, nullable=False)
user_id = Column(Integer, ForeignKey("user.id"), nullable=True) #연결
user = relationship("User", backref="question_users") #참조
(... 생략 ...)
user_id 속성은 User 모델을 Question 모델과 연결하기 위한 속성이고 user 속성은 Question 모델에서 User 모델을 참조하기 위한 속성이다. ForeignKey
와 relationship
은 질문과 답변 모델을 연결하는 부분에서 다루었으므로 자세한 설명은 생략한다.