Django でのデータベース構築方法を説明します。
昔は MySQL Workbench と simple-db-migrate を使っていましたが、Django 1.7 から標準で 便利な DB のマイグレーションツールが追加されたので、今はこれを使っています。
プログラムと一緒に DB もテキストで管理でき、バージョン管理もできるので、とても便利です。
Contents
バージョン
- Python 3.6.4
- Django 2.0.3
- MySQL 5.7
- mysqlclient 1.3.12
インストール
Python と Django のインストール
Python と Django のインストールについては、こちらを参考にしてください。
# yum install -y https://centos7.iuscommunity.org/ius-release.rpm # yum install -y python36u python36u-libs python36u-devel python36u-pip # pip install django
MySQL のインストール
MySQL のインストールについては、こちらを参考にしてください。
Python を ius リポジトリでインストールした場合、MySQL リポジトリと衝突します。
先に ius リポジトリを disable にしてください。
# yum-config-manager --disable ius # yum install mysql mysql-devel mysql-server mysql-utilities
mysqlclient のインストール
Django から MySQL に接続するために、mysqlclient をインストールします。
# pip install mysqlclient
設定
MySQL の設定
MySQL の起動
MySQL を起動し、初期パスワードを確認しましょう。
# systemctl start mysqld.service # grep 'temporary password' /var/log/mysqld.log 2018-04-14T14:54:06.927256Z 1 [Note] A temporary password is generated for root@localhost: <_k2T*MxLT!e
MySQL のパスワード
初期パスワードを確認したら、別のパスワードに変更しましょう。
[root@localhost ~]# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 5.7.21 Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> set password=password('Eba7|B33veK+'); Query OK, 0 rows affected, 1 warning (0.00 sec) mysql>
パスワードは、MySQL のパスワードのポリシーに合ったものを設定します。
MySQL のデータベース作成
Django で DB のマイグレーションする前に、データベースを先に作ります。
utf8mb4 を使います。
$ mysql -u root -p -e 'create database dbmigrate default character set utf8mb4'
Django の設定
settings.py
Django のプロジェクトとアプリケーションを作成し、MySQL に接続するための設定をします。プロジェクトとアプリケーションの作成方法については、こちらを参考にしてください。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app', ] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'dbmigrate', 'USER': 'root', 'PASSWORD': 'Eba7|B33veK+', 'OPTIONS': { 'charset': 'utf8mb4', } } }
app/models.py
次は下記のように models.py を作成します。細かい説明すると話が長くなってしまいますので、今回は割愛します。
from django.db import models class TestTable1(models.Model): column1 = models.IntegerField() column2 = models.CharField(max_length=100) column3 = models.BooleanField() created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) class Meta: db_table = 'test_table1'; class TestTable2(models.Model): test_table1 = models.ForeignKey(TestTable1, on_delete=models.CASCADE) column1 = models.TextField() created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) class Meta: db_table = 'test_table2';
tree
こんな感じの構成になりました。
[vagrant@localhost dbmigrate]$ tree . ├── app │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── dbmigrate │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py 4 directories, 15 files [vagrant@localhost dbmigrate]$
マイグレーション
makemigrations
それでは、先ほど作成した models.py を元にテーブルを作成します。
まず、DB マイグレート用ファイルを makemigrations コマンドで生成します。
[vagrant@localhost dbmigrate]$ python3.6 manage.py makemigrations Migrations for 'app': app/migrations/0001_initial.py - Create model TestTable1 - Create model TestTable2 [vagrant@localhost dbmigrate]$
migrations というディレクトリと以下の 0001_initial.py ファイルが作成されました。
# Generated by Django 2.0.3 on 2018-04-14 18:14 from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='TestTable1', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('column1', models.IntegerField()), ('column2', models.CharField(max_length=100)), ('column3', models.BooleanField()), ('created', models.DateTimeField(auto_now_add=True)), ('modified', models.DateTimeField(auto_now=True)), ], options={ 'db_table': 'test_table1', }, ), migrations.CreateModel( name='TestTable2', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('column1', models.TextField()), ('created', models.DateTimeField(auto_now_add=True)), ('modified', models.DateTimeField(auto_now=True)), ('test_table1', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.TestTable1')), ], options={ 'db_table': 'test_table2', }, ), ]
migrate
次に、先ほど作成した、0001_initial.py を使用して、MySQL にテーブルを作成します。テーブルの作成は、migrate コマンドを使用します。
[vagrant@localhost dbmigrate]$ python3.6 manage.py migrate Operations to perform: Apply all migrations: admin, app, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying app.0001_initial... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying sessions.0001_initial... OK [vagrant@localhost dbmigrate]$
自分で作成した models.py 以外にも、たくさんのテーブルが作成されます。これは、Django のデフォルトで、INSTALL_APPS などに様々なモジュールが定義されているためです。
それでは、実際に作成されたテーブルを確認してみます。
[vagrant@localhost dbmigrate]$ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 25 Server version: 5.7.21 MySQL Community Server (GPL) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use dbmigrate Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show create table test_table1; +-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | test_table1 | CREATE TABLE `test_table1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `column1` int(11) NOT NULL, `column2` varchar(100) NOT NULL, `column3` tinyint(1) NOT NULL, `created` datetime(6) NOT NULL, `modified` datetime(6) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 | +-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.01 sec) mysql> show create table test_table2; +-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | test_table2 | CREATE TABLE `test_table2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `column1` longtext NOT NULL, `created` datetime(6) NOT NULL, `modified` datetime(6) NOT NULL, `test_table1_id` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `test_table2_test_table1_id_39d002b8_fk_test_table1_id` (`test_table1_id`), CONSTRAINT `test_table2_test_table1_id_39d002b8_fk_test_table1_id` FOREIGN KEY (`test_table1_id`) REFERENCES `test_table1` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 | +-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql>
正常に作成されたようですね。
まとめ
駆け足でしたが、Django の DB マイグレーションについて説明しました。
models.py にカラムを追加したり、削除したりして、makemigrations コマンドを叩くと、alter 用のマイグレーションファイルを生成してくれますので、そのあたりも問題なく使えます。
使い慣れるとたくさんのメリットがあるので、Django の DB マイグレーションは是非使っていきましょう!