DjangoでCREATE DATABASEを自動化する(あるいはrake db:create的な何か)
問題意識
DjangoではRails同様migrationの仕組みがあるわけだが、Databaseの作成はマニュアル操作でやることを想定しているっぽい。
Djangoデフォルトではsqliteのファイルが出来上がりそのDBを使うように設定されている。
この場合はpython manage.py migrate
を実行すればそのままテーブルの作成が成功する(CREATE DATABSASEを手動で操作する必要はない)
しかしMySQLなどを使う場合はCREATE DATABASEなどを手動で実行しなければならない。
Railsにはrake db:create
のようにDatabaseの作成もコマンドで自動でやってくれるので、Djangoでもそういうのしたかった。
解決策
今回はカスタムコマンド(Railsでいうところのrake taskのようなもの)として実装する方法をとってみた。
記事にあるように、polls/management/commands/
以下にcreatedb.py
のようなファイルを作る。なおpip moduleはDjango推奨のmysqlclient
を使用する想定なので、pip install mysqlclient
などでインストールされていることが前提。
from django.core.management.base import BaseCommand, CommandError import MySQLdb class Command(BaseCommand): help = 'Create database' def handle(self, *args, **options): print('create database!') db = MySQLdb.connect(host='mysql', user='root', passwd='password1') cursor = db.cursor() sql = 'CREATE DATABASE IF NOT EXISTS `polls_development` DEFAULT CHARACTER SET `utf8mb4`' cursor.execute(sql) db.close()
IF NOT EXISTS
が有効なmysqlバージョン限定となるが、これを付けることによりすでにDatabaseが存在する場合のエラーハンドリングを気にしなくてよくなる。また文字コードもutf8mb4
としておく。
Database名を**_development
としたのはRails的なあれを持ち込んでしまった(良いのか悪いのはわからない)。
ついでにDROP DATABASEのコマンドも用意しておく。
from django.core.management.base import BaseCommand, CommandError import MySQLdb class Command(BaseCommand): help = 'Drop database' def handle(self, *args, **options): print('Drop database!') db = MySQLdb.connect(host='mysql', user='root', passwd='password1') cursor = db.cursor() sql = 'DROP DATABASE IF EXISTS `veritas_development`' cursor.execute(sql) db.close()
これで以下のようなコマンドでDatabaseの作成と削除をコマンド1つでできるようになった。
$ python3 manage.py createdb