DB migration
* DB: mariadb(mysql)
* Docker==20.10.21
* docker-compose==1.29.2
* alembic==1.9.2
* mysql connector install
-> $pip install mysql-connector-python
[migration project 폴더 구조]
.
├── alembic.ini
├── db_data # 원래 존재하던 db 데이터!
├── dbconf # db
├── docker-compose.yml # db docker-compose 파일
├── groupware_songdev # migration 후 생성된 폴더
└── migration # 가상환경
[init migration 할 때 생성된 폴더 구조]
├── alembic.ini
├── groupware_songdev
│ ├── README
│ ├── env.py
│ ├── script.py.mako
│ └── versions
1. alembic.ini : env.py 파일에서 config 로 사용되는 설정파일
2. env.py : db migration 시 사용되는 서버 연결 및 migration 실행 코드
3. script.py.mako : migration script template 파일
4. versions : migration 할 script code 가 들어갈 폴더
* 1. pip install alembic
* 2. docker-compose.yml 작성
version: '3.3'
services:
db:
image: mariadb/server:10.3
container_name: 'gw-migration-db'
ports:
- "${DB_PORT}:3306"
volumes:
- ./db_data:/var/lib/mysql
- ./dbconf/conf.d:/etc/mysql/conf.d
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
env_file: ./.env
environment:
TZ: "Asia/Seoul"
* 3. .env 파일 작성
DB_HOST = db
DB_PORT = 3306
MYSQL_ROOT_PASSWORD=songmoana
MYSQL_DATABASE=songmoana-migration
MYSQL_USER=songmoana
MYSQL_PASSWORD=0322
DB 가 기존에 존재한다면 여기부터 따 라 하 긔
* 4. $alembic init {migration 환경명} -> migration 폴더 생성

* 5. alembic.ini 파일에 db 인스턴스 주소 입력
# sqlalchemy.url = driver://user:pass@localhost/dbname
sqlalchemy.url = mysql+mysqlconnector://songmoana:0322@192.168.0.38:3307/songmoana-migration
-> 이렇게 하면 매번 주소를 변경해야해서 번거로움
-> env.py 에 sqlalchemy.url 을 수동으로 설정 (new!)
config = context.config # 원래있는거
if not config.get_main_option('sqlalchemy.url'):
config.set_main_option('sqlalchemy.url', 'mysql+mysqlconnector://{username}:{password}@{host}:{port}/{db_name}'.format(username='suprauser',password='supra',host='db',port='3307',db_name ='songmoana-migration'))
* 6. migration script 작성
$ alembic revision -m "first_migration_script_template"

"""
First migration script template
Revision ID: 1f486dc9fc67
Revises:
Create Date: 2023-01-19 10:17:43.896087
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '1f486dc9fc67' # migration script 가 동작했는지 확인
down_revision = None # migration script 가 동작했는지 확인
branch_labels = None
depends_on = None
def upgrade() -> None:
pass
def downgrade() -> None:
pass
* upgrade 함수는 이 migration을 적용했을 때 사용할 스크립트가 들어가며, downgrade는 migration
이후 다시 롤백할 경우 발생.
$ alembic upgrade [revision_hash]
$ alembic downgrade [revision_hash or current_revision +- 1]
upgrade: 명령어와 함께 revision 해쉬를 입력하면 해당 hash에 맞는 migration 스크립트의
upgrade 함수를 순차적으로 호출하여 migration 진행.
downgrade : 현재의 revision 에서 +- 숫자를 조정 입력하여 롤백과 업그레이드 반복 가능
# 1. upgrade 함수를 활용해서 groupware_notice 테이블에 img_url 컬럼을 추가한다.
# 2. upgrade 함수를 활용해서 images 테이블의 crop_status 컬럼 타입을 수정한다.
# 3. downgrade 함수를 활용해서 groupware_notice 테이블에 추가한 것을 삭제한다.
def upgrade():
op.add_column('groupware_notice', Column('img_url', LONGTEXT))
op.alter_column('images', 'crop_status', type_=sa.SmallInteger)
def downgrade() -> None:
op.drop_column('groupware_notice', 'img_url')
* 위의 코드 작성 후
$alembic upgrade 1f486dc9fc67 : 해당 revision 으로 감
$alembic upgrade head : 가장 상위의 revision 으로 감

$alembic downgrade -1 : 바로 전의 상태로 돌아가는 것
$alembic downgrade base : 초기 상태로 돌아감

요즘 관심있는 글이네요 좋은 글 감사합니다 :)