DockerでMySQLとDjangoを連携！初心者が実践

# はじめに

こんにちは、Python初心者のkeitaMaxです。

前回DjangoとMySQLのコンテナを立ち上げました、

https://qiita.com/keitaMax/items/d19b7458c388c4507b4c

今回はDjangoとMySQLを繋げてマイグレーションファイルを流して確認するところまで実践していこうと思います。

# mysqlclientをインストール

以下コマンドで`mysqlclient`をインストールします。

```
pip isntall mysqlclient
```

また、`docker/app/requirements.txt`に`mysqlclient`を追加しておきます。

```txt:docker/app/requirements.txt
Django==5.0

mysqlclient

```

# Djangoのsettings.pyを変更する

でファルとでは以下のようにsqliteの設定になっています。
```py:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
```
上を以下のようにmysqlの設定に修正します。
```py:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database',
        'USER': 'user',
        'PASSWORD': 'password',
        'HOST': 'db',
        'PORT': '3306',
    }
}
```

# マイグレーションを流す

以下のコマンドでマイグレーションの確認をします。
```
python3 manage.py showmigrations
```
```
root@ada83e062183:/code# python manage.py showmigrations
admin
 [ ] 0001_initial
 [ ] 0002_logentry_remove_auto_add
 [ ] 0003_logentry_add_action_flag_choices
auth
 [ ] 0001_initial
 [ ] 0002_alter_permission_name_max_length
 [ ] 0003_alter_user_email_max_length
 [ ] 0004_alter_user_username_opts
 [ ] 0005_alter_user_last_login_null
 [ ] 0006_require_contenttypes_0002
 [ ] 0007_alter_validators_add_error_messages
 [ ] 0008_alter_user_username_max_length
 [ ] 0009_alter_user_last_name_max_length
 [ ] 0010_alter_group_name_max_length
 [ ] 0011_update_proxy_permissions
 [ ] 0012_alter_user_first_name_max_length
contenttypes
 [ ] 0001_initial
 [ ] 0002_remove_content_type_name
sessions
 [ ] 0001_initial
root@ada83e062183:/code# 
```

[]の中に何も文字が入っていないのがマイグレーションがまだ実行されていないものです。

以下のコマンドで実行します。

```
python3 manage.py migrate
```
```
root@ada83e062183:/code# python manage.py migrate
Operations to perform:
  Apply all migrations: admin, 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 admin.0003_logentry_add_action_flag_choices... 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 auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK
root@ada83e062183:/code# 
```
これで試しに`showmigrations`でちゃんと実行できているか確認してみます。

```
root@ada83e062183:/code# python manage.py showmigrations
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
 [X] 0012_alter_user_first_name_max_length
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
sessions
 [X] 0001_initial
root@ada83e062183:/code# 
```

`X`がついているのでちゃんと実行されているようです。

# スーパーユーザを作成する

以下のコマンドでスーパーユーザを作成します。

```
python manage.py createsuperuser
```

実行するといくつか質問されるので答えます。

```
root@ada83e062183:/code# python manage.py createsuperuser
Username (leave blank to use 'root'): 
Email address: xxxxxxxxxxxxx@gmail.com
Password: 
Password (again): 
The password is too similar to the email address.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
root@ada83e062183:/code# 
```
`successfully`になれば作成完了です。

以下のURLにアクセスして実際にログインできるか確かめてみましょう。

```
http://localhost:8000/admin/login/
```

![スクリーンショット 2024-07-18 14.11.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/ca3d80ae-532f-f332-4667-1e77dfcb3c23.png)

ここに先ほど登録したUsernameとPasswordを入力しログインボタンを押します。

![スクリーンショット 2024-07-18 14.12.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/68f6d6c1-8fd7-b07d-b726-228bf3f0cfd3.png)

こんな感じでログインした後の画面ができていれば問題ありません。

# MySQLに値が本当に入っているかを確認する

以下のコマンドでMySQLのコンテナに入ります。

```
docker compose -it exec db psql
```

パスワードを聞かれるので答えます。前回`password`に設定したのでそれを入力します。

```
django-docker-example % docker compose exec db mysql  -u user -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 8.3.0 MySQL Community Server - GPL

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

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> 
```

これでmysqlコンテナの中に入りました。

以下のコマンドを実行して、作成したテーブルを確認してみます。

```
mysql> use database;
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 tables;
+----------------------------+
| Tables_in_database         |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
10 rows in set (0.00 sec)

mysql> 
```
無事入っていそうです。

また、先ほど作成したスーパーユーザが入っていることを以下のコマンドで確認します。

```
SELECT * FROM auth_user;
```

```
mysql> SELECT * FROM auth_user;
+----+------------------------------------------------------------------------------------------+------------+--------------+----------+------------+-----------+----------------------------------+----------+-----------+----------------------------+
| id | password                                                                                 | last_login | is_superuser | username | first_name | last_name | email                            | is_staff | is_active | date_joined                |
+----+------------------------------------------------------------------------------------------+------------+--------------+----------+------------+-----------+----------------------------------+----------+-----------+----------------------------+
|  1 | pbkdf2_sha256$720000$4FLjDnAJzCsAy4FWlvEnop$bY+TuxcUf/M2vujU7+/KsUe0OU+fxji80mw+Vj7liaw= | NULL       |            1 | root     |            |           | xxxxxxx@gmail.com |        1 |         1 | 2024-07-18 06:07:01.132470 |
+----+------------------------------------------------------------------------------------------+------------+--------------+----------+------------+-----------+----------------------------------+----------+-----------+----------------------------+
1 row in set (0.00 sec)

mysql> 
```

しっかり入っていそうです。


# おわりに

以上でDockerでMySQLとDjangoを起動して接続することができました。

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！

# 参考

https://qiita.com/bakupen/items/f23ce3d2325b4491a2dd

# 次の記事

https://qiita.com/keitaMax/items/c898d0364cd153f90e9d