migration์ด๋, DB ์ํฐํฐ ์ฝ๋์ ๋ณํ๋ฅผ ์๋์ผ๋ก ๊ฐ์งํ๊ณ ์ค์ DB์ ๋ฐ์ํด ์ฃผ๋ ๊ฒ์ด๋ค.
์ฐธ๊ณ : Python Flask Docker Migrations
ํ์ฌ๋ docker๋ฅผ ์ฌ์คํํ๊ฑฐ๋ ๋น๋๋ฅผ ๋ค์ ํด๋ ์ปฌ๋ผ ๋ณ๊ฒฝํ ๊ฒ ๋ฐ์๋์ง ์์
[์ด์ ํ๋ณด]
์ฝ๋ ์์ ํ๋ ๊ฒ ์ค์๊ฐ ๋ฐ์์ด ์ ๋จ โ ๋ฐ์ ์ ๋จ
flask ์คํํ๋ ๋ช
๋ น์ด๊ฐ app์์ create_app์ ์ ๊ฑฐ์น๊ณ ๊ทธ๋ฅ ์กด์ฌํ๋ app์ ๊ทธ๋๋ก ๋ถ๋ฌ์จ๋ค?
โ app.logger.info ์ฐ์ด๋ณด๋๊น ์ ์ผ ๋จผ์ ์คํํจ.
else: db.init_app()์ด๋ผ๋ ๊ฒ ๊ทธ๋ฅ DB์ ํด๋นํ๋ ํ
์ด๋ธ์ด ์กด์ฌํ๋ ์ง๋ง ๋ณด๊ณ
DB์ ์์ผ๋ฉด: ๋ฑํ ๋ฐ๊พธ์ง ์๋ ๊ฑฐ์
DB์ ์์ผ๋ฉด: ์๋ก ํ
์ด๋ธ ๋ง๋ค์ด์ค
โ ์ ๋ต!
DB์ ์์ผ๋ฉด ์์ ์ ๋ฐ๊พธ๊ณ , DB์ ์์ผ๋ฉด ์๋ก ํ ์ด๋ธ์ ์์ ๋ง๋ค์ด์ค.
์ฆ, ์ปฌ๋ผ ๋ณ๊ฒฝ์ ์ ํ ๊ฐ์งํ์ง ๋ชปํจ.
๋ง์ฝ ์ฝ๋ ์์ ์ํฐํฐ๊ฐ ์๋ค๊ฐ ์์ด์ก์ด๋ ๋ฑํ ์ญ์ ํ์ง ์์.
[init.py]
from flask import Flask
from flask_migrate import Migrate
from .models import db
from . import config
def create_app():
flask_app = Flask(__name__)
flask_app.logger.info('CREATE APP __INIT__')
flask_app.config['SQLALCHEMY_DATABASE_URI'] = config.DATABASE_CONNECTION_URI
flask_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
flask_app.app_context().push()
db.init_app(flask_app)
migrate = Migrate(flask_app, db)
# flask-migrate ์ ์ฉ
db.create_all()
return flask_app
์ดํ, ํ์ฌ ์ปจํ ์ด๋๋ฅผ ์คํ์์ผ๋๊ณ
version: "3.8"
services:
web:
build:
context: .
env_file:
- .env
ports:
- 5000:5000
environment:
- FLASK_APP=./src/app.py
volumes:
- ./:/app
postgres:
container_name: postgres
image: postgres:latest
ports:
- 5432:5432
environment:
- POSTGRES_DB=${PG_DB}
- POSTGRES_USER=${PG_USER}
- POSTGRES_PASSWORD=${PG_PASSWORD}
volumes:
- postgres:/var/lib/postgres
pgadmin:
container_name: pgadmin
image: dpage/pgadmin4
ports:
- 8088:80
environment:
- PGADMIN_DEFAULT_EMAIL=${PG_ADMIN_EMAIL}
- PGADMIN_DEFAULT_PASSWORD=${PGADMIN_DEFAULT_PASSWORD}
volumes:
postgres:
ํฐ๋ฏธ๋์ ๋ค์๊ณผ ๊ฐ์ด ๋ช ๋ น์ด๋ค์ ์์ฑํด ์ค๋ค.
docker exec [์ปจํ
์ด๋_์์ด๋] flask db init
# migration์ ํด๋น ์ฑ์ ์ ์ฉํ๊ฒ ๋ค๊ณ ์ ์ธ, ์ด ๊ฒฐ๊ณผ๋ก migrations ํด๋๊ฐ ์์ฑ๋จ.
docker exec [์ปจํ
์ด๋_์์ด๋] flask db migrate
# ์ฝ๋์์ DB ์ํฐํฐ์ ๋ณํ๋ฅผ ์๋์ ์ผ๋ก ๊ฐ์ง. ์ด ๊ฒฐ๊ณผ๋ก versions/2cd568bbbbe1_.py ๊ฐ์ ๊ฒ ์์ฑ๋จ.
docker exec [์ปจํ
์ด๋_์์ด๋] flask db upgrade
# migrate ๋ช
๋ น์ด๋ก ๊ฐ์งํ ์ํฐํฐ ๋ณํ๋ฅผ ์ค์ DB์ ๋ฐ์
์๋๋ ๋ผ์ดํ์ฌ์ดํด์ ์ ์ด ๋ณธ ๊ฒ์ด๋ค.
DB ์ํฐํฐ์ ๊ดํ ์ฝ๋ ๋ณ๊ฒฝ
โ ๋์ปค ์ปจํ
์ด๋ ์ฌ์คํํ๋ฉฐ ๋์์ ๋ง์ด๊ทธ๋ ์ด์
์ํ
โ ์ค์ DB์ ๋ฐ์
โ ์๋ฒ ์คํ
์ด๋ DockerFile์ CMD ๋ช ๋ น์ด์ .sh ํ์ผ ์คํ์ ์ถ๊ฐํ๋ค.
๊ธฐ์กด DockerFile
# syntax=docker/dockerfile:1
FROM python:3.8-slim-buster
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"]
์์ ํ DockerFile
# syntax=docker/dockerfile:1
FROM python:3.8-slim-buster
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
CMD [ "/bin/bash", "/app/docker-entrypoint.sh"]
# CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"]
#!/bin/sh
flask db init
flask db migrate
flask db upgrade
python3 -m flask run --host=0.0.0.0
๊ทธ๋ฌ๋ฉด ์ด์ ๊ฐ์ด ํฐ๋ฏธ๋์ด ์์ฃผ ์ ๋์จ๋ค.
๊ธฐ์กด์ ์ ์๋ ์ํฐํฐ๋ฅผ ๋ณ๊ฒฝํ๊ณ ๋์ปค ์ปจํ ์ด๋๋ฅผ ์ฌ์คํํด๋ ์ ๋๋ค.
flask db init์ด ์ด๋ฏธ ํ๋ฒ ๋ถ๋ ธ๊ธฐ ๋๋ฌธ์ ์๋ฌ ๋ฉ์์ง(Error: Directory migrations already exists and is not empty
)๋ฅผ ์ก์ถํ์ง๋ง, ์ด๊ฑธ๋ก ์ธํด ์ sh ํ์ผ์ ์คํํ๋ค๊ฐ ์ค๋จํ์ง ์์ผ๋ ์ผ๋จ ์ ๋ ๊ฒ ๋๊ณ ์ฐ์.
ํ๋ก์ ํธ ๊ตฌ์กฐ๋ค. ์์ง ํ ์ด ํ๋ก์ ํธ ๋จ๊ณ๋ผ์ ์ ๋ฆฌ๊ฐ ์ ์๋ ์ํ๋ผ๋ ์ .. ์ฐธ๊ณ ๋ฐ๋๋ค..
โโโ Dockerfile
โโโ README.md
โโโ docker-compose.dev.yml
โโโ docker-entrypoint.sh
โโโ migrations
โ โโโ README
โ โโโ alembic.ini
โ โโโ env.py
โ โโโ script.py.mako
โ โโโ versions
โ โโโ 2cd568bbbbe1_.py
โ โโโ a9bfee46c75b_.py
โ โโโ ae72eeaaa4f3_.py
โโโ requirements.txt
โโโ src
โโโ __init__.py
โโโ app.py
โโโ config.py
โโโ database.py
โโโ models.py
7 directories, 28 files
migrations ํด๋ ๋ฃ์ด๋ ๋๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
์๋ฌด๋๋ docker-entrypoint.sh๋ก ์์ ๋์ปค ์คํ๋ flask migrate์ python3 flask run ๋ช ๋ น์ด๋ฅผ ๊ฐ์ด ์ผ๊ณ , ๊ฐ์ ์ปจํ ์ด๋์์ ์คํํ๋ค ๋ณด๋ ๋งค๋ฒ ์ํฐํฐ ์์ฑ์ ๋ณ๊ฒฝํ์ ๋ ์๋น์ค ์ปจํ ์ด๋๋ฅผ ๊ป๋ค๊ฐ ์ผ์ผ ํด์ ๋ถํธํ๋ค.
์ฃผ๋ก ํ์ง์์๋ flask migrate๋ฅผ ๋ค๋ฅธ ๋ณ๊ฐ์ ์ปจํ ์ด๋๋ก ๋ถ๋ฆฌํด์ ์ฌ์ฉํ๋? ๊ทธ๋ ๊ฒ ํด์ ์ป๋ ์ ์ด ๋ฌด์์ผ๊น?
...์ผ๋จ ์ด๋ง ํ๊ณ .. ๋ด์ผ ๊ธฐ๋ง์ธ ๊ณ์ ์ ์กฐ๊ธ์ด๋ผ๋ ๊ณต๋ถํด์ผ๊ฒ ๋ค...