DjangoでMigrationsのリセット方法(既存のデータベースを残したまま)のイメージ画像

DjangoでMigrationsのリセット方法(既存のデータベースを残したまま)

  • 公開日:2019/05/06
  • 更新日:2019/05/06
  • 投稿者:n bit

何らかの理由によりDjangoのMigrationsをリセットする必要性が発生した場合にデータベース内のデータは残したまま履歴をリセットする方法を解説します。既に運用中でデータベース内のデータを削除することができない場合に有効です。

  • Python
  • Django

この記事は約 分で読めます。(文字)

DjangoでMigrationsのリセット
または、ロールバックする方法
(既存のデータベースを残したまま)

それではDjangoのMigrationsをリセット、または、ロールバックする方法を解説していきます。

DjangoのMigrations履歴をリセットする方法はいくつかありますが、今回はデータベースの内のデータを残したままMigrationsのみリセットする方法の解説です。

最初にリセット前の確認から行っていきましょう。

リセット前の確認処理

既存のmodelsがデータベースに適合しているか確認しておきます。適合を確認するには『makemigrations』コマンドを実行しましょう。

$ python manage.py makemigrations

コマンド実行後にエラーが表示されなければ大丈夫です。

また、modelsのMigrations処理が残っていないか『No changes detected』が表示されていることを確認しておきましょう。まだ適用していないMigrationsが残っている場合は先に実行しておいてください。

 現状のMigrations履歴を確認

今まで行っているMigrationsの履歴を確認します。履歴を確認するには『showmigrations』コマンドを実行しましょう。

$ python manage.py showmigrations

今までのMigrationsの履歴が表示されます。

admin

[X] 0001_initial
[X] 0002_・・・・・
[X] 0003_・・・・・
auth
[X] 0001_initial
[X] 0002_・・・・・
[X] 0003_・・・・・
app2
[X] 0001_initial
contenttypes
[X] 0001_initial
[X] 0002_・・・・・
app3
[X] 0001_initial
app1
[X] 0001_initial
[X] 0002_・・・・・
[X] 0003_・・・・・
reversion
[X] 0001_・・・・・
sessions
[X] 0001_initial
app4
[X] 0001_initial

Migrations履歴を削除

一通りの確認作業が完了しましたのでMigrations履歴を削除します。履歴を削除するには『migrate --fakeappName zero』コマンドを実行しましょう。

  • appName にはMigrations履歴を削除するアプリケーション名を指定してください。

今回の事例では『app1』の履歴を削除対象とします。

$ python manage.py migrate --fake app1 zero

以下の様にapp1に関連する履歴に対して処理が実行されました。

Operations to perform:

Unapply all migrations: app1
Running migrations:
Rendering model states... DONE
Unapplying app4.0001_initial... FAKED
Unapplying reversion.0001_・・・・・... FAKED
Unapplying app1.0003_・・・・・... FAKED
Unapplying app1.0002_・・・・・... FAKED
Unapplying app3.0001_initial... FAKED
Unapplying app2.0001_initial... FAKED
Unapplying admin.0003_・・・・・... FAKED
Unapplying admin.0002_・・・・・... FAKED
Unapplying admin.0001_initial... FAKED
Unapplying app1.0001_initial... FAKED

 再度Migrations履歴を確認

削除コマンド実行後にMigrationsの履歴を再度確認します。履歴を確認するには『showmigrations』コマンドを実行しましょう。

$ python manage.py showmigrations

Migrationsの履歴から削除対象となった項目の『[X]』が『[ ]』に変更されていることが確認できます。

admin

[ ] 0001_initial
[ ] 0002_・・・・・
[ ] 0003_・・・・・
auth
[X] 0001_initial
[X] 0002_・・・・・
[X] 0003_・・・・・
app2
[ ] 0001_initial
contenttypes
[X] 0001_initial
[X] 0002_・・・・・
app3
[ ] 0001_initial
app1
[ ] 0001_initial
[ ] 0002_・・・・・
[ ] 0003_・・・・・
reversion
[ ] 0001_・・・・・
sessions
[X] 0001_initial
app4
[ ] 0001_initial

Migrationsファイルを削除

不要になったMigrations履歴ファイルを削除します。各migrationsディレクトリ内の『__ init__.py』ファイル以外のすべてのファイルを削除します。

  • 相対パスで指定していますので対象プロジェクトのディレクトリ内で実行してください。
$ find . -path "*/migrations/*.py" -not -name "__init__.py" -delete

$ find . -path "*/migrations/*.pyc" -delete

 再度Migrations履歴を確認

Migrations履歴ファイルが削除されているか確認します。履歴を確認するには『showmigrations』コマンドを実行しましょう。

$ python manage.py showmigrations

正しく履歴ファイルが削除されていれば『(no migrations)』が表示されています。

admin

[ ] 0001_initial
[ ] 0002_・・・・・
[ ] 0003_・・・・・
auth
[X] 0001_initial
[X] 0002_・・・・・
[X] 0003_・・・・・
app2
(no migrations)
contenttypes
[X] 0001_initial
[X] 0002_・・・・・
app3
(no migrations)
app1
(no migrations)
reversion
[ ] 0001_・・・・・
sessions
[X] 0001_initial
app4
(no migrations)

新たにMigrationsを作成

新たにMigrationsを作成します。作成するには『makemigrations』コマンドを実行しましょう。

$ python manage.py makemigrations

今回削除対象となっていたmodelsのMigrationsが作成されます。

Migrations for 'app2':

app2/migrations/0001_initial.py
- Create model ・・・・・
- Create model ・・・・・
- Create model ・・・・・



app2/migrations/0002_・・・・・.py
- Add field ・・・・・
- Add field ・・・・・
- Add field ・・・・・



Migrations for 'editcal':
app3/migrations/0001_initial.py
- Create model ・・・・・
- Create model ・・・・・
- Create model ・・・・・



app3/migrations/0002_・・・・・.py
- Add field ・・・・・
- Add field ・・・・・
- Add field ・・・・・



Migrations for 'register':
app1/migrations/0001_initial.py
- Create model ・・・・・
- Create model ・・・・・
- Create model ・・・・・



Migrations for 't1word':
app4/migrations/0001_initial.py
- Create model ・・・・・
- Create model ・・・・・
- Create model ・・・・・


不要コマンドの削除

もし、Migrationsファイル内のSQLコマンドで飛ばしたいコマンドが含まれている場合は、vimなどで不要な行をコメントアウト、もしくは、削除しておきましょう。

特にロールバックさせる必要がない場合はこのセクションを飛ばしてください。

  • ex:0001_initial.py 内のコマンドコメントアウト
$ vim register/migrations/0001_initial.py

migrate

『makemigrations』コマンドで作成したmigrationsファイルをmigrateするのですが、既にデータベースのテーブルは作成されているためfakeコマンドを使って実行します。

$ python manage.py migrate --fake-initial

各アプリケーションのinitialファイルが『FAKED』で実行されました。

Operations to perform:

Apply all migrations: admin, auth, app2, contenttypes, app3, app1, reversion, sessions, app4
Running migrations:
Applying app1.0001_initial... FAKED
Applying admin.0001_initial... FAKED
Applying admin.0002_・・・・・... OK
Applying admin.0003_・・・・・... OK
Applying app2.0001_initial... FAKED
Applying app2.0002_・・・・・... FAKED
Applying app3.0001_initial... FAKED
Applying app3.0002_・・・・・... FAKED
Applying reversion.0001_・・・・・... FAKED
Applying app4.0001_initial... FAKED

Migrations履歴を確認

最後にMigrationsの不要な履歴を削除して再構築されているか確認します。履歴を確認するには『showmigrations』コマンドを実行しましょう。

admin

[X] 0001_initial
[X] 0002_・・・・・
[X] 0003_・・・・・
auth
[X] 0001_initial
[X] 0002_・・・・・
[X] 0003_・・・・・
app2
[X] 0001_initial
[X] 0002_auto_20190501_1916
contenttypes
[X] 0001_initial
[X] 0002_・・・・・
app3
[X] 0001_initial
[X] 0002_auto_20190501_1916
app1
[X] 0001_initial
[X] 0002_・・・・・
[X] 0003_・・・・・
reversion
[X] 0001_・・・・・
sessions
[X] 0001_initial
app4
[X] 0001_initial

ロールバックコマンドの実行

ロールバックさせたコマンドは必要に応じてmodels内を修正しmigrateしておきましょう。

$ python manage.py makemigrations app1

Migrations for 'app1':
app1/migrations/0002_auto_20190501_1930.py
- Add field FIELD_NAME1 to CLASS_NAME
- Add field FIELD_NAME2 to CLASS_NAME


$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, app2, contenttypes, app3, app1, reversion, sessions, app4
Running migrations:
Applying app1.0002_auto_20190501_1930... OK

今日のdot

今回はMigrations履歴のリセット方法について解説しました。途中ロールバックさせる方法も解説していますが、こちらの方法はMigration中にエラー等が発生しmodels内の変更処理が正しく適用できなくなった場合などにも有効です。