1. 인스턴스의 이전
- 클라우드를 사용한다면 다른 인스턴스 혹은 다른 리전으로 이전해야할 경우
2. 특정 Entity에 대한 변경 요청
- 기능을 새로 넣기위해 추가 컬럼이 필요할 경우
3. 일부 영속된 데이터를 특정 데이터로 변경
pip install alembic
alembic init [디렉터리 이름]
ex) alembic init migrations
초기화 이후 디렉터리 이름으로 폴더가 만들어지며, 그 폴더안에 Alembic 과 관련된 파일이 생성됩니다.
alembic.ini 파일은 폴더 밖 경로에 만들어집니다.
sqlalchemy.url = sqlite:///[DB 명].db
주의 !
ini 파일이기 때문에 python에서 제공하는 String 관련 함수를 사용할 수 없으며 오직 정적 문자열만 이용해야한다.
그런데 이렇게 설정하면 환경별로 마이그레이션을 할 때마다 인스턴스 주소를 바꿔줘야하는 불편함이 생긴다.
이런 경우, alembic.ini 파일에 있는 sqlalchemy.url 변수를 제거한 후 env.py 파일에서 sqlalchemy.url을 수동으로 설정할 수 있는 방법이 있다.
env.py
config = context.config
if not config.get_main_option("sqlalchemy.url") :
config.set_main_option("sqlalchemy.url", DB 정보)
)
- ex) MySQL 적용
config = context.config
if not config.get_main_option("sqlalchemy.url") :
config.set_main_option("sqlalchemy.url",
"mysql+pymysql://{username}:{password}@{host}:{port}/{db_name}".format(
username="root",
password="1234",
host="localhost",
port="3306",
db_name="test_db"
)
- ex) sqlite 적용
config = context.config
if not config.get_main_option("sqlalchemy.url") :
config.set_main_option("sqlalchemy.url", sqlite://blacklist.db)
script.py.mako
"""${message}
Revision ID: ${up_revision}
Revises: ${down_revision | comma,n}
Create Date: ${create_date}
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
import sqlmodel <--------------- 구문 추가 --------------->
${imports if imports else ""}
# revision identifiers, used by Alembic.
revision: str = ${repr(up_revision)}
down_revision: Union[str, None] = ${repr(down_revision)}
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
def upgrade() -> None:
${upgrades if upgrades else "pass"}
def downgrade() -> None:
${downgrades if downgrades else "pass"}
from logging.config import fileConfig
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from alembic import context
from sqlmodel import SQLModel <--------------- 구문 추가 --------------->
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.config_file_name is not None:
fileConfig(config.config_file_name)
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
# Base = declarative_base()
target_metadata = SQLModel.metadata <--------------- 구문 추가 --------------->
# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.
def run_migrations_offline() -> None:
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online() -> None:
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
connection=connection, target_metadata=target_metadata
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
alembic revision -m "commit 메시지 작성"
ex)
alembic revision -m "first alembic"
alembic revision --autogenerate -m "first alembic"
명령어 수행 시, 자동으로 version 폴더 안에 마이그레이션 코드가 만들어집니다.
그리고 내부 upgrade와 downgrade에 필요한 DB 정보의 추가, 수정 내역이 있는지 확인하시고, 잘 작동하시면 Alembic 적용이 성공적으로 된 것입니다.