Djangoのマイグレーションをロールバック、元に戻す方法

「あーここはForeignKeyじゃなくてOneToOneFieldにしたいなー」とか、モデルを修正する場合に、一度実行したマイグレーションを取り消しす必要があります。その方法のメモです。

ロールバックの手順

  1. python manage.py showmigrations でマイグレーション履歴を確認
  2. python manage.py migrate APPLICATION_NAME MIGRATION_NAME で指定したマイグレーションまで戻る
  3. マイグレーションファイルの削除

showmigrationsでマイグレーション履歴を確認

python manage.py showmigrations を実行すると、次のようにマイグレーションの履歴を確認できます。

...
your_app #<-アプリケーション名
 [X] 0001_initial #<-マイグレーション名
 [X] 0002_introduction_privacy
 [X] 0003_introduction_privacy
 [X] 0004_statement

アプリケーション名と戻りたいマイグレーション名をメモします。

migrateでロールバック

先ほどメモしたアプリケーション名とマイグレーション名を指定し、 migrate コマンドを実行します。

python manage.py migrate APPLICATION_NAME MIGRATION_NAME

#例
python manage.py migrate your_app 0001_initial

もう一度 showmigrations を実行すると、過去のマイグレーションの時点に戻っていることがわかります。

...
your_app
 [X] 0001_initial
 [ ] 0002_introduction_privacy
 [ ] 0003_introduction_privacy
 [ ] 0004_statement

マイグレーションファイルの削除

必要に応じて、マイグレーションファイルとキャッシュを削除します。

今回は 0001_initial の時点まで戻ったので、それ以外のファイルを消します。

マイグレーションファイルはアプリケーションディレクトリの migrations 配下にあります。

your_app
...
├── migrations
│   ├── 0001_initial.py
│   ├── 0002_introduction_privacy.py #<-削除する
│   ├── 0003_introduction_privacy.py #<-削除する
│   ├── 0004_statement.py #<-削除する
│   ├── __init__.py
│   └── __pycache__
│       ├── 0001_initial.cpython-37.pyc
│       ├── 0002_introduction_privacy.cpython-37.pyc #<-削除する
│       ├── 0003_introduction_privacy.cpython-37.pyc #<-削除する
│       ├── 0004_statement.cpython-37.pyc #<-削除する
│       └── __init__.cpython-37.pyc
...

もう一度 showmigrations を実行すると、マイグレーションがスッキリ削除されているのがわかります。

完全に初期化したい場合

次のコマンドでinitialのマイグレーションも含め、初期化できます。

python manage.py migrate APPLICATION_NAME zero

まとめ

これで遠慮なくモデルの修正ができます。やったね!