Djangoでマイグレーションを行う + MySQL(初心者向け)

シェアする

Django でのデータベース構築方法を説明します。

昔は MySQL Workbench と simple-db-migrate を使っていましたが、Django 1.7 から標準で 便利な DB のマイグレーションツールが追加されたので、今はこれを使っています。

プログラムと一緒に DB もテキストで管理でき、バージョン管理もできるので、とても便利です。

バージョン

  • 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 マイグレーションは是非使っていきましょう!

シェアする

フォローする