이번 포스트에서는
- DB연결을 위한
alembic.ini
를 수정하기 - Migration Script를 생성 및 작성하여 upgrade, downgrade Migration 하기
에 대해 다뤄본다.
이전 포스트를 보려면? ✋
우선, alembic.ini
파일을 연다. DB경로를 설정해 줄 것 이다.
본 포스트에서는 alembic의 사용법에 집중하기 위해 별다른 설치가 없는 sqlite를 사용한다.
아래와 같이 추가해준다
sqlalchemy.url = sqlite:///db_file.db
만일 postgresql, mysql을 연결하고싶다면?
sqlalchemy.url = postgresql://username:password@127.0.0.1:5432
이와 같이 추가하면 된다
이제, alembic revision
명령을 이용하여 새로운 revision을 생성해본다
나는 example 이라는 이름으로 revision을 지정해주었다.
(venv) $ alembic revision -m "example"
Generating /path/to/my_folder/practice/versions/f09152543072_example.py ... done
f09152543072_example.py
라는 파일이 생겼고 현재까지의 디렉토리 구조는 아래와 같다
- my_folder
- alembic.ini
- practice
- README
- env.py
- script.py.mako
- versions
- f09152543072_example.py
- venv
f09152543072_example.py
은 아래와 같이 구성되어있다.
"""example
Revision ID: f09152543072
Revises:
Create Date: 2020-03-17 21:38:40.688600
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'f09152543072'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
pass
def downgrade():
pass
위 코드를 보면 현재의 revision과 downgrade revision 에 대한 변수가 있다
또한 빈 상태의 upgrade()
와 downgrade()
함수를 볼 수 있다.
다음의 revision을 만들게 되면 해당 revision의 down_revision
은 위 revision값이 될 것이다.
또한, 숙지하고 있어야 할 점이 있다.
upgrade()
함수는 필수적이며, downgrade()
함수는 선택으로 사용하면 된다.
즉, 맨 처음의 revision에서는 upgrade()
만 작성하고 downgrade()
에는 지금과 같이 비워두거나, table drop과 같은 구성을 해주면 된다.
그럼 이제 database에 변화를 주기위해 upgrade()
함수를 채워보자
손님에 대한 테이블을 SQLAlchemy 를 이용해 작성해본다. (이름 컬럼의 사이즈는 50 으로 지정해주었다)
downgrade 하는 경우엔 customer 테이블을 비우는 것으로 하였다
def upgrade():
op.create_table(
'customer',
sa.Column('id', sa.Integer, primary_key=True),
# 다른 손님과 식별 위한 고유키 id
sa.Column('firstname', sa.String(50), nullable=False),
# 이름
sa.Column('lastname', sa.String(50), nullable=False),
# 성
sa.Column('recentvisit', sa.DateTime)
# 최근 방문일자
)
def downgrade():
op.drop_table('customer')
그리고 이제 migration을 해본다
head는 가장 상위의 revision으로 향하는 tag이다
(venv) $ 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 -> f09152543072, example
이제 우리가 사용하는 db파일인 db_file.db
를 확인해보자
기존에 db_file.db가 없더라도
alembic upgrade head
명령을 통해 파일이 생성됨을 확인 할 수 있다mysql, postgresql와 같은 경우 DB세팅을 해주고 시작하면 된다
테이블과 컬럼들이 성공적으로 구성됨을 알 수 있다.
그럼 이제, 두번째 revision 파일을 만들어보자
기존 customer 테이블
에서 middlename 컬럼
을 추가할 것이다
따라서 가독성있게 revision 이름을 "add a middlename" 으로 정해 생성해본다.
(venv) $ alembic revision -m "add a middlename"
Generating /path/to/my_folder/practice/versions/5e13c5f76fac_add_a_middlename.py ... done
5e13c5f76fac_add_a_middlename.py
파일은 아래와 같이 구성되어있다.
"""add a middlename
Revision ID: 5e13c5f76fac
Revises: f09152543072
Create Date: 2020-03-17 22:10:31.522687
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '5e13c5f76fac'
down_revision = 'f09152543072'
# down_revision이 우리가 처음 생성한 "example" revision임을 알 수 있다.
branch_labels = None
depends_on = None
def upgrade():
pass
def downgrade():
pass
upgrade()
함수에는 middlename
컬럼을 추가해주고
downgrade()
함수에는 처음 revision인 example의 상태로 돌아가기 위해 middlename
컬럼을 drop하도록 구성하였다
def upgrade():
op.add_column('customer', sa.Column('middlename', sa.String(50)))
def downgrade():
with op.batch_alter_table('customer') as batch_op:
batch_op.drop_column('middlename')
sqlite에는 ALTER와 DROP을 지원하지 않기 때문에 위와 같은 방법으로 컬럼을 제거하였다.
mysql, postgresql 에서는 아래와 같이 하면 된다
def downgrade():
op.drop_column('customer', 'middlename')
# sqlite은 지원X
이제 alembic upgrade head
명령을 통해 migration을 진행해본다
(venv) $ 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 f09152543072 -> 5e13c5f76fac, add a middlename
아래와 같이 middlename
컬럼이 추가됨을 확인 할 수 있다
alembic의 migration 기록(history)을 보고싶으면 alembic history
명령을 통해 확인 가능하다
(venv) $ alembic history
f09152543072 -> 5e13c5f76fac (head), add a middlename
<base> -> f09152543072, example
이제, downgrade를 수행해보도록 한다
downgrade는 upgrade와는 달리 head를 사용할 수 없다
Partial Revision Identifiers 혹은 Relative Migration Identifiers 의 방법으로 downgrade 할 수 있다.
upgrade 경우에서도 사용 가능하다
alembic downgrade f09152543072
# Partial Revision Identifiers는 revision번호를 입력하는 방법이다 (절대적 위치)
alembic downgrade -1
# Relative Migration Identifiers는 상대적인 위치의 이동이 가능하다
# -2도 물론 가능하다. 지금 상황의 경우엔 -2는 drop customer table의 결과를 가지게 된다
따라서, alembic downgrade -1
이나 alembic downgrade <down_revision의 값>
으로 입력해야한다
alembic downgrade -1
명령으로 downgrade 해본다
(venv) $ alembic downgrade -1
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running downgrade 5e13c5f76fac -> f09152543072, add a middlename
이제 customer 테이블에서 middlename 컬럼이 사라진 것을 볼 수 있을 것이다.
이것으로 alembic.ini를 수정하여 DB연결하기, Migration Script를 생성 및 작성하여 upgrade, downgrade 하기 를 모두 마쳤다.
다음 포스트에서는 ForeignKey 컬럼을 나타내고 migration하는 방법에 대해 다룬다
이 글이 도움이 되셨다면 공감버튼 부탁드립니다
'Back-end' 카테고리의 다른 글
JPA, Postgres earthdistance를 이용하여 사용자 근처 가맹점 조회 API 구현하기 (0) | 2020.07.24 |
---|---|
WSL환경에서 Docker-compose 사용하기 (0) | 2020.04.26 |
alembic을 이용해 DB 마이그레이션 하기 (1) (0) | 2020.03.16 |
카카오i 스킬서버 library 개발 기록 (0) | 2019.12.29 |
django-rest-framework에서 Token기반인증 사용 Views 작성(Functional based Views) (0) | 2019.12.06 |
댓글